mirror of
https://github.com/servo/servo.git
synced 2025-09-10 15:08:21 +01:00
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:
parent
d1da1a995c
commit
c97ec1b2fb
17 changed files with 129 additions and 68 deletions
|
@ -2,6 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
|
||||||
use crossbeam_channel::{Receiver, select};
|
use crossbeam_channel::{Receiver, select};
|
||||||
use devtools_traits::DevtoolScriptControlMsg;
|
use devtools_traits::DevtoolScriptControlMsg;
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ pub(crate) fn run_worker_event_loop<T, WorkerMsg, Event>(
|
||||||
let event = select! {
|
let event = select! {
|
||||||
recv(worker_scope.control_receiver()) -> msg => T::from_control_msg(msg.unwrap()),
|
recv(worker_scope.control_receiver()) -> msg => T::from_control_msg(msg.unwrap()),
|
||||||
recv(task_queue.select()) -> msg => {
|
recv(task_queue.select()) -> msg => {
|
||||||
task_queue.take_tasks(msg.unwrap());
|
task_queue.take_tasks(msg.unwrap(), &HashSet::new());
|
||||||
T::from_worker_msg(task_queue.recv().unwrap())
|
T::from_worker_msg(task_queue.recv().unwrap())
|
||||||
},
|
},
|
||||||
recv(devtools_receiver) -> msg => T::from_devtools_msg(msg.unwrap()),
|
recv(devtools_receiver) -> msg => T::from_devtools_msg(msg.unwrap()),
|
||||||
|
@ -72,7 +74,7 @@ pub(crate) fn run_worker_event_loop<T, WorkerMsg, Event>(
|
||||||
while !scope.is_closing() {
|
while !scope.is_closing() {
|
||||||
// Batch all events that are ready.
|
// Batch all events that are ready.
|
||||||
// The task queue will throttle non-priority tasks if necessary.
|
// The task queue will throttle non-priority tasks if necessary.
|
||||||
match task_queue.take_tasks_and_recv() {
|
match task_queue.take_tasks_and_recv(&HashSet::new()) {
|
||||||
Err(_) => match devtools_receiver.try_recv() {
|
Err(_) => match devtools_receiver.try_recv() {
|
||||||
Ok(message) => sequential.push(T::from_devtools_msg(message)),
|
Ok(message) => sequential.push(T::from_devtools_msg(message)),
|
||||||
Err(_) => break,
|
Err(_) => break,
|
||||||
|
|
|
@ -52,7 +52,6 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::htmlelement::HTMLElement;
|
use crate::dom::htmlelement::HTMLElement;
|
||||||
use crate::dom::window::Window;
|
use crate::dom::window::Window;
|
||||||
use crate::script_runtime::{CanGc, JSContext, JSContext as SafeJSContext};
|
use crate::script_runtime::{CanGc, JSContext, JSContext as SafeJSContext};
|
||||||
use crate::script_thread::ScriptThread;
|
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#htmlconstructor>
|
/// <https://html.spec.whatwg.org/multipage/#htmlconstructor>
|
||||||
fn html_constructor(
|
fn html_constructor(
|
||||||
|
@ -391,14 +390,6 @@ fn get_constructor_object_from_local_name(
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn pop_current_element_queue(can_gc: CanGc) {
|
|
||||||
ScriptThread::pop_current_element_queue(can_gc);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn push_new_element_queue() {
|
|
||||||
ScriptThread::push_new_element_queue();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn call_html_constructor<T: DerivedFrom<Element> + DomObject>(
|
pub(crate) fn call_html_constructor<T: DerivedFrom<Element> + DomObject>(
|
||||||
cx: JSContext,
|
cx: JSContext,
|
||||||
args: &CallArgs,
|
args: &CallArgs,
|
||||||
|
|
|
@ -19,9 +19,7 @@ use script_bindings::settings_stack::StackEntry;
|
||||||
|
|
||||||
use crate::DomTypes;
|
use crate::DomTypes;
|
||||||
use crate::dom::bindings::codegen::{InterfaceObjectMap, PrototypeList};
|
use crate::dom::bindings::codegen::{InterfaceObjectMap, PrototypeList};
|
||||||
use crate::dom::bindings::constructor::{
|
use crate::dom::bindings::constructor::call_html_constructor;
|
||||||
call_html_constructor, pop_current_element_queue, push_new_element_queue,
|
|
||||||
};
|
|
||||||
use crate::dom::bindings::conversions::DerivedFrom;
|
use crate::dom::bindings::conversions::DerivedFrom;
|
||||||
use crate::dom::bindings::error::{Error, report_pending_exception, throw_dom_exception};
|
use crate::dom::bindings::error::{Error, report_pending_exception, throw_dom_exception};
|
||||||
use crate::dom::bindings::principals::PRINCIPALS_CALLBACKS;
|
use crate::dom::bindings::principals::PRINCIPALS_CALLBACKS;
|
||||||
|
@ -33,6 +31,7 @@ use crate::dom::globalscope::GlobalScope;
|
||||||
use crate::dom::windowproxy::WindowProxyHandler;
|
use crate::dom::windowproxy::WindowProxyHandler;
|
||||||
use crate::realms::InRealm;
|
use crate::realms::InRealm;
|
||||||
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
|
||||||
|
use crate::script_thread::ScriptThread;
|
||||||
|
|
||||||
#[derive(JSTraceable, MallocSizeOf)]
|
#[derive(JSTraceable, MallocSizeOf)]
|
||||||
/// Static data associated with a global object.
|
/// Static data associated with a global object.
|
||||||
|
@ -185,10 +184,10 @@ impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_new_element_queue() {
|
fn push_new_element_queue() {
|
||||||
push_new_element_queue()
|
ScriptThread::custom_element_reaction_stack().push_new_element_queue()
|
||||||
}
|
}
|
||||||
fn pop_current_element_queue(can_gc: CanGc) {
|
fn pop_current_element_queue(can_gc: CanGc) {
|
||||||
pop_current_element_queue(can_gc)
|
ScriptThread::custom_element_reaction_stack().pop_current_element_queue(can_gc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reflect_dom_object<T, U>(obj: Box<T>, global: &U, can_gc: CanGc) -> DomRoot<T>
|
fn reflect_dom_object<T, U>(obj: Box<T>, global: &U, can_gc: CanGc) -> DomRoot<T>
|
||||||
|
|
|
@ -1044,8 +1044,12 @@ enum BackupElementQueueFlag {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
|
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
|
||||||
|
/// # Safety
|
||||||
|
/// This can be shared inside an Rc because one of those Rc copies lives
|
||||||
|
/// inside ScriptThread, so the GC can always reach this structure.
|
||||||
#[derive(JSTraceable, MallocSizeOf)]
|
#[derive(JSTraceable, MallocSizeOf)]
|
||||||
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
||||||
|
#[cfg_attr(crown, crown::unrooted_must_root_lint::allow_unrooted_in_rc)]
|
||||||
pub(crate) struct CustomElementReactionStack {
|
pub(crate) struct CustomElementReactionStack {
|
||||||
stack: DomRefCell<Vec<ElementQueue>>,
|
stack: DomRefCell<Vec<ElementQueue>>,
|
||||||
backup_queue: ElementQueue,
|
backup_queue: ElementQueue,
|
||||||
|
|
|
@ -124,7 +124,7 @@ use crate::dom::cdatasection::CDATASection;
|
||||||
use crate::dom::comment::Comment;
|
use crate::dom::comment::Comment;
|
||||||
use crate::dom::compositionevent::CompositionEvent;
|
use crate::dom::compositionevent::CompositionEvent;
|
||||||
use crate::dom::cssstylesheet::CSSStyleSheet;
|
use crate::dom::cssstylesheet::CSSStyleSheet;
|
||||||
use crate::dom::customelementregistry::CustomElementDefinition;
|
use crate::dom::customelementregistry::{CustomElementDefinition, CustomElementReactionStack};
|
||||||
use crate::dom::customevent::CustomEvent;
|
use crate::dom::customevent::CustomEvent;
|
||||||
use crate::dom::document_event_handler::DocumentEventHandler;
|
use crate::dom::document_event_handler::DocumentEventHandler;
|
||||||
use crate::dom::documentfragment::DocumentFragment;
|
use crate::dom::documentfragment::DocumentFragment;
|
||||||
|
@ -565,6 +565,10 @@ pub(crate) struct Document {
|
||||||
/// this `Document` will not perform any more rendering updates.
|
/// this `Document` will not perform any more rendering updates.
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
current_canvas_epoch: RefCell<Epoch>,
|
current_canvas_epoch: RefCell<Epoch>,
|
||||||
|
|
||||||
|
/// The global custom element reaction stack for this script thread.
|
||||||
|
#[conditional_malloc_size_of]
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -3261,6 +3265,7 @@ impl Document {
|
||||||
allow_declarative_shadow_roots: bool,
|
allow_declarative_shadow_roots: bool,
|
||||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||||
has_trustworthy_ancestor_origin: bool,
|
has_trustworthy_ancestor_origin: bool,
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
) -> Document {
|
) -> Document {
|
||||||
let url = url.unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap());
|
let url = url.unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap());
|
||||||
|
|
||||||
|
@ -3434,6 +3439,7 @@ impl Document {
|
||||||
resize_observer_started_observing_target: Cell::new(false),
|
resize_observer_started_observing_target: Cell::new(false),
|
||||||
waiting_on_canvas_image_updates: Cell::new(false),
|
waiting_on_canvas_image_updates: Cell::new(false),
|
||||||
current_canvas_epoch: RefCell::new(Epoch(0)),
|
current_canvas_epoch: RefCell::new(Epoch(0)),
|
||||||
|
custom_element_reaction_stack,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3536,6 +3542,7 @@ impl Document {
|
||||||
allow_declarative_shadow_roots: bool,
|
allow_declarative_shadow_roots: bool,
|
||||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||||
has_trustworthy_ancestor_origin: bool,
|
has_trustworthy_ancestor_origin: bool,
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> DomRoot<Document> {
|
) -> DomRoot<Document> {
|
||||||
Self::new_with_proto(
|
Self::new_with_proto(
|
||||||
|
@ -3557,6 +3564,7 @@ impl Document {
|
||||||
allow_declarative_shadow_roots,
|
allow_declarative_shadow_roots,
|
||||||
inherited_insecure_requests_policy,
|
inherited_insecure_requests_policy,
|
||||||
has_trustworthy_ancestor_origin,
|
has_trustworthy_ancestor_origin,
|
||||||
|
custom_element_reaction_stack,
|
||||||
can_gc,
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3581,6 +3589,7 @@ impl Document {
|
||||||
allow_declarative_shadow_roots: bool,
|
allow_declarative_shadow_roots: bool,
|
||||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||||
has_trustworthy_ancestor_origin: bool,
|
has_trustworthy_ancestor_origin: bool,
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> DomRoot<Document> {
|
) -> DomRoot<Document> {
|
||||||
let document = reflect_dom_object_with_proto(
|
let document = reflect_dom_object_with_proto(
|
||||||
|
@ -3602,6 +3611,7 @@ impl Document {
|
||||||
allow_declarative_shadow_roots,
|
allow_declarative_shadow_roots,
|
||||||
inherited_insecure_requests_policy,
|
inherited_insecure_requests_policy,
|
||||||
has_trustworthy_ancestor_origin,
|
has_trustworthy_ancestor_origin,
|
||||||
|
custom_element_reaction_stack,
|
||||||
)),
|
)),
|
||||||
window,
|
window,
|
||||||
proto,
|
proto,
|
||||||
|
@ -3736,6 +3746,7 @@ impl Document {
|
||||||
self.allow_declarative_shadow_roots(),
|
self.allow_declarative_shadow_roots(),
|
||||||
Some(self.insecure_requests_policy()),
|
Some(self.insecure_requests_policy()),
|
||||||
self.has_trustworthy_ancestor_or_current_origin(),
|
self.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
self.custom_element_reaction_stack.clone(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
new_doc
|
new_doc
|
||||||
|
@ -4413,6 +4424,10 @@ impl Document {
|
||||||
pub(crate) fn highlighted_dom_node(&self) -> Option<DomRoot<Node>> {
|
pub(crate) fn highlighted_dom_node(&self) -> Option<DomRoot<Node>> {
|
||||||
self.highlighted_dom_node.get()
|
self.highlighted_dom_node.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn custom_element_reaction_stack(&self) -> Rc<CustomElementReactionStack> {
|
||||||
|
self.custom_element_reaction_stack.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
|
@ -4444,6 +4459,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
|
||||||
doc.allow_declarative_shadow_roots(),
|
doc.allow_declarative_shadow_roots(),
|
||||||
Some(doc.insecure_requests_policy()),
|
Some(doc.insecure_requests_policy()),
|
||||||
doc.has_trustworthy_ancestor_or_current_origin(),
|
doc.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
doc.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,7 @@ impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
|
||||||
loader,
|
loader,
|
||||||
Some(self.document.insecure_requests_policy()),
|
Some(self.document.insecure_requests_policy()),
|
||||||
self.document.has_trustworthy_ancestor_or_current_origin(),
|
self.document.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
self.document.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -184,6 +185,7 @@ impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
|
||||||
self.document.allow_declarative_shadow_roots(),
|
self.document.allow_declarative_shadow_roots(),
|
||||||
Some(self.document.insecure_requests_policy()),
|
Some(self.document.insecure_requests_policy()),
|
||||||
self.document.has_trustworthy_ancestor_or_current_origin(),
|
self.document.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
self.document.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -104,6 +104,7 @@ impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
|
||||||
false,
|
false,
|
||||||
Some(doc.insecure_requests_policy()),
|
Some(doc.insecure_requests_policy()),
|
||||||
doc.has_trustworthy_ancestor_or_current_origin(),
|
doc.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
doc.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
// Step switch-1. Parse HTML from a string given document and compliantString.
|
// Step switch-1. Parse HTML from a string given document and compliantString.
|
||||||
|
@ -131,6 +132,7 @@ impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
|
||||||
false,
|
false,
|
||||||
Some(doc.insecure_requests_policy()),
|
Some(doc.insecure_requests_policy()),
|
||||||
doc.has_trustworthy_ancestor_or_current_origin(),
|
doc.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
doc.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
// Step switch-1. Create an XML parser parser, associated with document,
|
// Step switch-1. Create an XML parser parser, associated with document,
|
||||||
|
|
|
@ -326,7 +326,7 @@ impl Node {
|
||||||
|
|
||||||
/// Implements the "unsafely set HTML" algorithm as specified in:
|
/// Implements the "unsafely set HTML" algorithm as specified in:
|
||||||
/// <https://html.spec.whatwg.org/multipage/#concept-unsafely-set-html>
|
/// <https://html.spec.whatwg.org/multipage/#concept-unsafely-set-html>
|
||||||
pub fn unsafely_set_html(
|
pub(crate) fn unsafely_set_html(
|
||||||
target: &Node,
|
target: &Node,
|
||||||
context_element: &Element,
|
context_element: &Element,
|
||||||
html: DOMString,
|
html: DOMString,
|
||||||
|
@ -2926,6 +2926,7 @@ impl Node {
|
||||||
document.allow_declarative_shadow_roots(),
|
document.allow_declarative_shadow_roots(),
|
||||||
Some(document.insecure_requests_policy()),
|
Some(document.insecure_requests_policy()),
|
||||||
document.has_trustworthy_ancestor_or_current_origin(),
|
document.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
document.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
DomRoot::upcast::<Node>(document)
|
DomRoot::upcast::<Node>(document)
|
||||||
|
|
|
@ -8,6 +8,7 @@ use std::borrow::Cow;
|
||||||
use std::cell::{Cell, Ref, RefCell, RefMut};
|
use std::cell::{Cell, Ref, RefCell, RefMut};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::collections::vec_deque::VecDeque;
|
use std::collections::vec_deque::VecDeque;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
use crossbeam_channel::{Receiver, Sender, unbounded};
|
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::root::{Dom, DomRoot};
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
use crate::dom::comment::Comment;
|
use crate::dom::comment::Comment;
|
||||||
|
use crate::dom::customelementregistry::CustomElementReactionStack;
|
||||||
use crate::dom::document::Document;
|
use crate::dom::document::Document;
|
||||||
use crate::dom::documenttype::DocumentType;
|
use crate::dom::documenttype::DocumentType;
|
||||||
use crate::dom::element::{Element, ElementCreator};
|
use crate::dom::element::{Element, ElementCreator};
|
||||||
|
@ -228,6 +230,8 @@ pub(crate) struct Tokenizer {
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
url: ServoUrl,
|
url: ServoUrl,
|
||||||
parsing_algorithm: ParsingAlgorithm,
|
parsing_algorithm: ParsingAlgorithm,
|
||||||
|
#[conditional_malloc_size_of]
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tokenizer {
|
impl Tokenizer {
|
||||||
|
@ -246,6 +250,7 @@ impl Tokenizer {
|
||||||
None => ParsingAlgorithm::Normal,
|
None => ParsingAlgorithm::Normal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let custom_element_reaction_stack = document.custom_element_reaction_stack();
|
||||||
let tokenizer = Tokenizer {
|
let tokenizer = Tokenizer {
|
||||||
document: Dom::from_ref(document),
|
document: Dom::from_ref(document),
|
||||||
receiver: tokenizer_receiver,
|
receiver: tokenizer_receiver,
|
||||||
|
@ -253,6 +258,7 @@ impl Tokenizer {
|
||||||
nodes: RefCell::new(HashMap::new()),
|
nodes: RefCell::new(HashMap::new()),
|
||||||
url,
|
url,
|
||||||
parsing_algorithm: algorithm,
|
parsing_algorithm: algorithm,
|
||||||
|
custom_element_reaction_stack,
|
||||||
};
|
};
|
||||||
tokenizer.insert_node(0, Dom::from_ref(document.upcast()));
|
tokenizer.insert_node(0, Dom::from_ref(document.upcast()));
|
||||||
|
|
||||||
|
@ -397,7 +403,14 @@ impl Tokenizer {
|
||||||
.GetParentNode()
|
.GetParentNode()
|
||||||
.expect("append_before_sibling called on node without parent");
|
.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) {
|
fn append(&self, parent: ParseNodeId, node: NodeOrText, can_gc: CanGc) {
|
||||||
|
@ -409,7 +422,14 @@ impl Tokenizer {
|
||||||
};
|
};
|
||||||
|
|
||||||
let parent = &**self.get_node(&parent);
|
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 {
|
fn has_parent_node(&self, node: ParseNodeId) -> bool {
|
||||||
|
@ -454,6 +474,7 @@ impl Tokenizer {
|
||||||
&self.document,
|
&self.document,
|
||||||
ElementCreator::ParserCreated(current_line),
|
ElementCreator::ParserCreated(current_line),
|
||||||
ParsingAlgorithm::Normal,
|
ParsingAlgorithm::Normal,
|
||||||
|
&self.custom_element_reaction_stack,
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
self.insert_node(node, Dom::from_ref(element.upcast()));
|
self.insert_node(node, Dom::from_ref(element.upcast()));
|
||||||
|
|
|
@ -52,12 +52,14 @@ impl Tokenizer {
|
||||||
fragment_context: Option<super::FragmentContext>,
|
fragment_context: Option<super::FragmentContext>,
|
||||||
parsing_algorithm: ParsingAlgorithm,
|
parsing_algorithm: ParsingAlgorithm,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let custom_element_reaction_stack = document.custom_element_reaction_stack();
|
||||||
let sink = Sink {
|
let sink = Sink {
|
||||||
base_url: url,
|
base_url: url,
|
||||||
document: Dom::from_ref(document),
|
document: Dom::from_ref(document),
|
||||||
current_line: Cell::new(1),
|
current_line: Cell::new(1),
|
||||||
script: Default::default(),
|
script: Default::default(),
|
||||||
parsing_algorithm,
|
parsing_algorithm,
|
||||||
|
custom_element_reaction_stack,
|
||||||
};
|
};
|
||||||
|
|
||||||
let quirks_mode = match document.quirks_mode() {
|
let quirks_mode = match document.quirks_mode() {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use base::cross_process_instant::CrossProcessInstant;
|
use base::cross_process_instant::CrossProcessInstant;
|
||||||
use base::id::PipelineId;
|
use base::id::PipelineId;
|
||||||
|
@ -57,6 +58,7 @@ use crate::dom::bindings::str::{DOMString, USVString};
|
||||||
use crate::dom::characterdata::CharacterData;
|
use crate::dom::characterdata::CharacterData;
|
||||||
use crate::dom::comment::Comment;
|
use crate::dom::comment::Comment;
|
||||||
use crate::dom::csp::{CspReporting, GlobalCspReporting, Violation, parse_csp_list_from_metadata};
|
use crate::dom::csp::{CspReporting, GlobalCspReporting, Violation, parse_csp_list_from_metadata};
|
||||||
|
use crate::dom::customelementregistry::CustomElementReactionStack;
|
||||||
use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
||||||
use crate::dom::documentfragment::DocumentFragment;
|
use crate::dom::documentfragment::DocumentFragment;
|
||||||
use crate::dom::documenttype::DocumentType;
|
use crate::dom::documenttype::DocumentType;
|
||||||
|
@ -244,6 +246,7 @@ impl ServoParser {
|
||||||
allow_declarative_shadow_roots,
|
allow_declarative_shadow_roots,
|
||||||
Some(context_document.insecure_requests_policy()),
|
Some(context_document.insecure_requests_policy()),
|
||||||
context_document.has_trustworthy_ancestor_or_current_origin(),
|
context_document.has_trustworthy_ancestor_or_current_origin(),
|
||||||
|
context_document.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1156,6 +1159,7 @@ fn insert(
|
||||||
reference_child: Option<&Node>,
|
reference_child: Option<&Node>,
|
||||||
child: NodeOrText<Dom<Node>>,
|
child: NodeOrText<Dom<Node>>,
|
||||||
parsing_algorithm: ParsingAlgorithm,
|
parsing_algorithm: ParsingAlgorithm,
|
||||||
|
custom_element_reaction_stack: &CustomElementReactionStack,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) {
|
) {
|
||||||
match child {
|
match child {
|
||||||
|
@ -1166,11 +1170,11 @@ fn insert(
|
||||||
let element_in_non_fragment =
|
let element_in_non_fragment =
|
||||||
parsing_algorithm != ParsingAlgorithm::Fragment && n.is::<Element>();
|
parsing_algorithm != ParsingAlgorithm::Fragment && n.is::<Element>();
|
||||||
if element_in_non_fragment {
|
if element_in_non_fragment {
|
||||||
ScriptThread::push_new_element_queue();
|
custom_element_reaction_stack.push_new_element_queue();
|
||||||
}
|
}
|
||||||
parent.InsertBefore(&n, reference_child, can_gc).unwrap();
|
parent.InsertBefore(&n, reference_child, can_gc).unwrap();
|
||||||
if element_in_non_fragment {
|
if element_in_non_fragment {
|
||||||
ScriptThread::pop_current_element_queue(can_gc);
|
custom_element_reaction_stack.pop_current_element_queue(can_gc);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
NodeOrText::AppendText(t) => {
|
NodeOrText::AppendText(t) => {
|
||||||
|
@ -1201,6 +1205,8 @@ pub(crate) struct Sink {
|
||||||
current_line: Cell<u64>,
|
current_line: Cell<u64>,
|
||||||
script: MutNullableDom<HTMLScriptElement>,
|
script: MutNullableDom<HTMLScriptElement>,
|
||||||
parsing_algorithm: ParsingAlgorithm,
|
parsing_algorithm: ParsingAlgorithm,
|
||||||
|
#[conditional_malloc_size_of]
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sink {
|
impl Sink {
|
||||||
|
@ -1278,6 +1284,7 @@ impl TreeSink for Sink {
|
||||||
&self.document,
|
&self.document,
|
||||||
ElementCreator::ParserCreated(self.current_line.get()),
|
ElementCreator::ParserCreated(self.current_line.get()),
|
||||||
parsing_algorithm,
|
parsing_algorithm,
|
||||||
|
&self.custom_element_reaction_stack,
|
||||||
CanGc::note(),
|
CanGc::note(),
|
||||||
);
|
);
|
||||||
Dom::from_ref(element.upcast())
|
Dom::from_ref(element.upcast())
|
||||||
|
@ -1347,6 +1354,7 @@ impl TreeSink for Sink {
|
||||||
Some(sibling),
|
Some(sibling),
|
||||||
new_node,
|
new_node,
|
||||||
self.parsing_algorithm,
|
self.parsing_algorithm,
|
||||||
|
&self.custom_element_reaction_stack,
|
||||||
CanGc::note(),
|
CanGc::note(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1366,7 +1374,14 @@ impl TreeSink for Sink {
|
||||||
|
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||||
fn append(&self, parent: &Dom<Node>, child: NodeOrText<Dom<Node>>) {
|
fn append(&self, parent: &Dom<Node>, child: NodeOrText<Dom<Node>>) {
|
||||||
insert(parent, None, child, self.parsing_algorithm, CanGc::note());
|
insert(
|
||||||
|
parent,
|
||||||
|
None,
|
||||||
|
child,
|
||||||
|
self.parsing_algorithm,
|
||||||
|
&self.custom_element_reaction_stack,
|
||||||
|
CanGc::note(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||||
|
@ -1479,6 +1494,7 @@ fn create_element_for_token(
|
||||||
document: &Document,
|
document: &Document,
|
||||||
creator: ElementCreator,
|
creator: ElementCreator,
|
||||||
parsing_algorithm: ParsingAlgorithm,
|
parsing_algorithm: ParsingAlgorithm,
|
||||||
|
custom_element_reaction_stack: &CustomElementReactionStack,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> DomRoot<Element> {
|
) -> DomRoot<Element> {
|
||||||
// Step 3.
|
// Step 3.
|
||||||
|
@ -1506,7 +1522,7 @@ fn create_element_for_token(
|
||||||
.perform_a_microtask_checkpoint(can_gc);
|
.perform_a_microtask_checkpoint(can_gc);
|
||||||
}
|
}
|
||||||
// Step 6.3
|
// Step 6.3
|
||||||
ScriptThread::push_new_element_queue()
|
custom_element_reaction_stack.push_new_element_queue()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 7.
|
// Step 7.
|
||||||
|
@ -1544,7 +1560,7 @@ fn create_element_for_token(
|
||||||
// Step 9.
|
// Step 9.
|
||||||
if will_execute_script {
|
if will_execute_script {
|
||||||
// Steps 9.1 - 9.2.
|
// Steps 9.1 - 9.2.
|
||||||
ScriptThread::pop_current_element_queue(can_gc);
|
custom_element_reaction_stack.pop_current_element_queue(can_gc);
|
||||||
// Step 9.3.
|
// Step 9.3.
|
||||||
document.decrement_throw_on_dynamic_markup_insertion_counter();
|
document.decrement_throw_on_dynamic_markup_insertion_counter();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ impl Tokenizer {
|
||||||
current_line: Cell::new(1),
|
current_line: Cell::new(1),
|
||||||
script: Default::default(),
|
script: Default::default(),
|
||||||
parsing_algorithm: ParsingAlgorithm::Normal,
|
parsing_algorithm: ParsingAlgorithm::Normal,
|
||||||
|
custom_element_reaction_stack: document.custom_element_reaction_stack(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let tb = XmlTreeBuilder::new(sink, Default::default());
|
let tb = XmlTreeBuilder::new(sink, Default::default());
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use data_url::mime::Mime;
|
use data_url::mime::Mime;
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use net_traits::request::InsecureRequestsPolicy;
|
use net_traits::request::InsecureRequestsPolicy;
|
||||||
|
@ -17,6 +19,7 @@ use crate::dom::bindings::inheritance::Castable;
|
||||||
use crate::dom::bindings::reflector::reflect_dom_object;
|
use crate::dom::bindings::reflector::reflect_dom_object;
|
||||||
use crate::dom::bindings::root::DomRoot;
|
use crate::dom::bindings::root::DomRoot;
|
||||||
use crate::dom::bindings::str::DOMString;
|
use crate::dom::bindings::str::DOMString;
|
||||||
|
use crate::dom::customelementregistry::CustomElementReactionStack;
|
||||||
use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
||||||
use crate::dom::location::Location;
|
use crate::dom::location::Location;
|
||||||
use crate::dom::node::Node;
|
use crate::dom::node::Node;
|
||||||
|
@ -44,6 +47,7 @@ impl XMLDocument {
|
||||||
doc_loader: DocumentLoader,
|
doc_loader: DocumentLoader,
|
||||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||||
has_trustworthy_ancestor_origin: bool,
|
has_trustworthy_ancestor_origin: bool,
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
) -> XMLDocument {
|
) -> XMLDocument {
|
||||||
XMLDocument {
|
XMLDocument {
|
||||||
document: Document::new_inherited(
|
document: Document::new_inherited(
|
||||||
|
@ -64,6 +68,7 @@ impl XMLDocument {
|
||||||
false,
|
false,
|
||||||
inherited_insecure_requests_policy,
|
inherited_insecure_requests_policy,
|
||||||
has_trustworthy_ancestor_origin,
|
has_trustworthy_ancestor_origin,
|
||||||
|
custom_element_reaction_stack,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,6 +87,7 @@ impl XMLDocument {
|
||||||
doc_loader: DocumentLoader,
|
doc_loader: DocumentLoader,
|
||||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||||
has_trustworthy_ancestor_origin: bool,
|
has_trustworthy_ancestor_origin: bool,
|
||||||
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> DomRoot<XMLDocument> {
|
) -> DomRoot<XMLDocument> {
|
||||||
let doc = reflect_dom_object(
|
let doc = reflect_dom_object(
|
||||||
|
@ -98,6 +104,7 @@ impl XMLDocument {
|
||||||
doc_loader,
|
doc_loader,
|
||||||
inherited_insecure_requests_policy,
|
inherited_insecure_requests_policy,
|
||||||
has_trustworthy_ancestor_origin,
|
has_trustworthy_ancestor_origin,
|
||||||
|
custom_element_reaction_stack,
|
||||||
)),
|
)),
|
||||||
window,
|
window,
|
||||||
can_gc,
|
can_gc,
|
||||||
|
|
|
@ -1535,6 +1535,7 @@ impl XMLHttpRequest {
|
||||||
false,
|
false,
|
||||||
Some(doc.insecure_requests_policy()),
|
Some(doc.insecure_requests_policy()),
|
||||||
doc.has_trustworthy_ancestor_origin(),
|
doc.has_trustworthy_ancestor_origin(),
|
||||||
|
doc.custom_element_reaction_stack(),
|
||||||
can_gc,
|
can_gc,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::option::Option;
|
use std::option::Option;
|
||||||
use std::result::Result;
|
use std::result::Result;
|
||||||
|
|
||||||
|
@ -397,10 +398,11 @@ impl ScriptThreadReceivers {
|
||||||
&self,
|
&self,
|
||||||
task_queue: &TaskQueue<MainThreadScriptMsg>,
|
task_queue: &TaskQueue<MainThreadScriptMsg>,
|
||||||
timer_scheduler: &TimerScheduler,
|
timer_scheduler: &TimerScheduler,
|
||||||
|
fully_active: &HashSet<PipelineId>,
|
||||||
) -> MixedMessage {
|
) -> MixedMessage {
|
||||||
select! {
|
select! {
|
||||||
recv(task_queue.select()) -> msg => {
|
recv(task_queue.select()) -> msg => {
|
||||||
task_queue.take_tasks(msg.unwrap());
|
task_queue.take_tasks(msg.unwrap(), fully_active);
|
||||||
let event = task_queue
|
let event = task_queue
|
||||||
.recv()
|
.recv()
|
||||||
.expect("Spurious wake-up of the event-loop, task-queue has no tasks available");
|
.expect("Spurious wake-up of the event-loop, task-queue has no tasks available");
|
||||||
|
@ -437,6 +439,7 @@ impl ScriptThreadReceivers {
|
||||||
pub(crate) fn try_recv(
|
pub(crate) fn try_recv(
|
||||||
&self,
|
&self,
|
||||||
task_queue: &TaskQueue<MainThreadScriptMsg>,
|
task_queue: &TaskQueue<MainThreadScriptMsg>,
|
||||||
|
fully_active: &HashSet<PipelineId>,
|
||||||
) -> Option<MixedMessage> {
|
) -> Option<MixedMessage> {
|
||||||
if let Ok(message) = self.constellation_receiver.try_recv() {
|
if let Ok(message) = self.constellation_receiver.try_recv() {
|
||||||
let message = message
|
let message = message
|
||||||
|
@ -449,7 +452,7 @@ impl ScriptThreadReceivers {
|
||||||
.ok()?;
|
.ok()?;
|
||||||
return MixedMessage::FromConstellation(message).into();
|
return MixedMessage::FromConstellation(message).into();
|
||||||
}
|
}
|
||||||
if let Ok(message) = task_queue.take_tasks_and_recv() {
|
if let Ok(message) = task_queue.take_tasks_and_recv(fully_active) {
|
||||||
return MixedMessage::FromScript(message).into();
|
return MixedMessage::FromScript(message).into();
|
||||||
}
|
}
|
||||||
if let Ok(message) = self.devtools_server_receiver.try_recv() {
|
if let Ok(message) = self.devtools_server_receiver.try_recv() {
|
||||||
|
|
|
@ -279,7 +279,7 @@ pub struct ScriptThread {
|
||||||
docs_with_no_blocking_loads: DomRefCell<HashSet<Dom<Document>>>,
|
docs_with_no_blocking_loads: DomRefCell<HashSet<Dom<Document>>>,
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
|
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
|
||||||
custom_element_reaction_stack: CustomElementReactionStack,
|
custom_element_reaction_stack: Rc<CustomElementReactionStack>,
|
||||||
|
|
||||||
/// Cross-process access to the compositor's API.
|
/// Cross-process access to the compositor's API.
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
|
@ -723,24 +723,21 @@ impl ScriptThread {
|
||||||
with_script_thread(|script_thread| script_thread.is_user_interacting.get())
|
with_script_thread(|script_thread| script_thread.is_user_interacting.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_fully_active_document_ids() -> HashSet<PipelineId> {
|
pub(crate) fn get_fully_active_document_ids(&self) -> HashSet<PipelineId> {
|
||||||
with_script_thread(|script_thread| {
|
self.documents
|
||||||
script_thread
|
.borrow()
|
||||||
.documents
|
.iter()
|
||||||
.borrow()
|
.filter_map(|(id, document)| {
|
||||||
.iter()
|
if document.is_fully_active() {
|
||||||
.filter_map(|(id, document)| {
|
Some(id)
|
||||||
if document.is_fully_active() {
|
} else {
|
||||||
Some(id)
|
None
|
||||||
} else {
|
}
|
||||||
None
|
})
|
||||||
}
|
.fold(HashSet::new(), |mut set, id| {
|
||||||
})
|
let _ = set.insert(id);
|
||||||
.fold(HashSet::new(), |mut set, id| {
|
set
|
||||||
let _ = set.insert(id);
|
})
|
||||||
set
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn find_window_proxy(id: BrowsingContextId) -> Option<DomRoot<WindowProxy>> {
|
pub(crate) fn find_window_proxy(id: BrowsingContextId) -> Option<DomRoot<WindowProxy>> {
|
||||||
|
@ -810,19 +807,13 @@ impl ScriptThread {
|
||||||
.register_paint_worklet_modules(name, properties, painter);
|
.register_paint_worklet_modules(name, properties, painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn push_new_element_queue() {
|
pub(crate) fn custom_element_reaction_stack() -> Rc<CustomElementReactionStack> {
|
||||||
with_script_thread(|script_thread| {
|
with_optional_script_thread(|script_thread| {
|
||||||
script_thread
|
script_thread
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
.custom_element_reaction_stack
|
.custom_element_reaction_stack
|
||||||
.push_new_element_queue();
|
.clone()
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn pop_current_element_queue(can_gc: CanGc) {
|
|
||||||
with_script_thread(|script_thread| {
|
|
||||||
script_thread
|
|
||||||
.custom_element_reaction_stack
|
|
||||||
.pop_current_element_queue(can_gc);
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1006,7 +997,7 @@ impl ScriptThread {
|
||||||
webxr_registry: state.webxr_registry,
|
webxr_registry: state.webxr_registry,
|
||||||
worklet_thread_pool: Default::default(),
|
worklet_thread_pool: Default::default(),
|
||||||
docs_with_no_blocking_loads: Default::default(),
|
docs_with_no_blocking_loads: Default::default(),
|
||||||
custom_element_reaction_stack: CustomElementReactionStack::new(),
|
custom_element_reaction_stack: Rc::new(CustomElementReactionStack::new()),
|
||||||
compositor_api: state.compositor_api,
|
compositor_api: state.compositor_api,
|
||||||
profile_script_events: opts.debug.profile_script_events,
|
profile_script_events: opts.debug.profile_script_events,
|
||||||
print_pwm: opts.print_pwm,
|
print_pwm: opts.print_pwm,
|
||||||
|
@ -1352,9 +1343,12 @@ impl ScriptThread {
|
||||||
|
|
||||||
// Receive at least one message so we don't spinloop.
|
// Receive at least one message so we don't spinloop.
|
||||||
debug!("Waiting for event.");
|
debug!("Waiting for event.");
|
||||||
let mut event = self
|
let fully_active = self.get_fully_active_document_ids();
|
||||||
.receivers
|
let mut event = self.receivers.recv(
|
||||||
.recv(&self.task_queue, &self.timer_scheduler.borrow());
|
&self.task_queue,
|
||||||
|
&self.timer_scheduler.borrow(),
|
||||||
|
&fully_active,
|
||||||
|
);
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
debug!("Handling event: {event:?}");
|
debug!("Handling event: {event:?}");
|
||||||
|
@ -1464,7 +1458,7 @@ impl ScriptThread {
|
||||||
// If any of our input sources has an event pending, we'll perform another iteration
|
// If any of our input sources has an event pending, we'll perform another iteration
|
||||||
// and check for more resize events. If there are no events pending, we'll move
|
// and check for more resize events. If there are no events pending, we'll move
|
||||||
// on and execute the sequential non-resize events we've seen.
|
// on and execute the sequential non-resize events we've seen.
|
||||||
match self.receivers.try_recv(&self.task_queue) {
|
match self.receivers.try_recv(&self.task_queue, &fully_active) {
|
||||||
Some(new_event) => event = new_event,
|
Some(new_event) => event = new_event,
|
||||||
None => break,
|
None => break,
|
||||||
}
|
}
|
||||||
|
@ -3422,6 +3416,7 @@ impl ScriptThread {
|
||||||
true,
|
true,
|
||||||
incomplete.load_data.inherited_insecure_requests_policy,
|
incomplete.load_data.inherited_insecure_requests_policy,
|
||||||
incomplete.load_data.has_trustworthy_ancestor_origin,
|
incomplete.load_data.has_trustworthy_ancestor_origin,
|
||||||
|
self.custom_element_reaction_stack.clone(),
|
||||||
can_gc,
|
can_gc,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,6 @@ use strum::VariantArray;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::worker::TrustedWorkerAddress;
|
use crate::dom::worker::TrustedWorkerAddress;
|
||||||
use crate::script_runtime::ScriptThreadEventCategory;
|
use crate::script_runtime::ScriptThreadEventCategory;
|
||||||
use crate::script_thread::ScriptThread;
|
|
||||||
use crate::task::TaskBox;
|
use crate::task::TaskBox;
|
||||||
use crate::task_source::TaskSourceName;
|
use crate::task_source::TaskSourceName;
|
||||||
|
|
||||||
|
@ -197,19 +196,18 @@ impl<T: QueuedTaskConversion> TaskQueue<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take all tasks again and then run `recv()`.
|
/// Take all tasks again and then run `recv()`.
|
||||||
pub(crate) fn take_tasks_and_recv(&self) -> Result<T, ()> {
|
pub(crate) fn take_tasks_and_recv(&self, fully_active: &HashSet<PipelineId>) -> Result<T, ()> {
|
||||||
self.take_tasks(T::wake_up_msg());
|
self.take_tasks(T::wake_up_msg(), fully_active);
|
||||||
self.recv()
|
self.recv()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Drain the queue for the current iteration of the event-loop.
|
/// Drain the queue for the current iteration of the event-loop.
|
||||||
/// Holding-back throttles above a given high-water mark.
|
/// Holding-back throttles above a given high-water mark.
|
||||||
pub(crate) fn take_tasks(&self, first_msg: T) {
|
pub(crate) fn take_tasks(&self, first_msg: T, fully_active: &HashSet<PipelineId>) {
|
||||||
// High-watermark: once reached, throttled tasks will be held-back.
|
// High-watermark: once reached, throttled tasks will be held-back.
|
||||||
const PER_ITERATION_MAX: u64 = 5;
|
const PER_ITERATION_MAX: u64 = 5;
|
||||||
let fully_active = ScriptThread::get_fully_active_document_ids();
|
|
||||||
// Always first check for new tasks, but don't reset 'taken_task_counter'.
|
// Always first check for new tasks, but don't reset 'taken_task_counter'.
|
||||||
self.process_incoming_tasks(first_msg, &fully_active);
|
self.process_incoming_tasks(first_msg, fully_active);
|
||||||
let mut throttled = self.throttled.borrow_mut();
|
let mut throttled = self.throttled.borrow_mut();
|
||||||
let mut throttled_length: usize = throttled.values().map(|queue| queue.len()).sum();
|
let mut throttled_length: usize = throttled.values().map(|queue| queue.len()).sum();
|
||||||
let mut task_source_cycler = TaskSourceName::VARIANTS.iter().cycle();
|
let mut task_source_cycler = TaskSourceName::VARIANTS.iter().cycle();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue