aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock40
-rw-r--r--Cargo.toml1
-rw-r--r--components/constellation/constellation.rs1
-rw-r--r--components/constellation/pipeline.rs7
-rw-r--r--components/script/dom/window.rs12
-rw-r--r--components/script/script_thread.rs7
-rw-r--r--components/servo/Cargo.toml1
-rw-r--r--components/servo/lib.rs5
-rw-r--r--components/servo_tracing/Cargo.toml21
-rw-r--r--components/servo_tracing/lib.rs394
-rw-r--r--components/shared/script/lib.rs4
-rw-r--r--ports/servoshell/Cargo.toml1
12 files changed, 447 insertions, 47 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e4ebac08f89..856e243b854 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -330,9 +330,9 @@ dependencies = [
[[package]]
name = "async-compression"
-version = "0.4.22"
+version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64"
+checksum = "b37fc50485c4f3f736a4fb14199f6d5f5ba008d7f28fe710306c92780f004c07"
dependencies = [
"brotli",
"flate2",
@@ -669,9 +669,9 @@ dependencies = [
[[package]]
name = "brotli"
-version = "7.0.0"
+version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd"
+checksum = "cf19e729cdbd51af9a397fb9ef8ac8378007b797f8273cfbfdf45dcaa316167b"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@@ -680,9 +680,9 @@ dependencies = [
[[package]]
name = "brotli-decompressor"
-version = "4.0.3"
+version = "5.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a334ef7c9e23abf0ce748e8cd309037da93e606ad52eb372e4ce327a0dcfbdfd"
+checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03"
dependencies = [
"alloc-no-stdlib",
"alloc-stdlib",
@@ -2029,7 +2029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -2555,7 +2555,7 @@ dependencies = [
"gobject-sys",
"libc",
"system-deps",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -3997,7 +3997,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi 0.5.0",
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -4250,14 +4250,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
dependencies = [
"cfg-if",
- "windows-targets 0.52.6",
+ "windows-targets 0.48.5",
]
[[package]]
name = "libm"
-version = "0.2.12"
+version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6d154aedcb0b7a1e91a3fddbe2a8350d3da76ac9d0220ae20da5c7aa8269612"
+checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72"
[[package]]
name = "libredox"
@@ -4321,6 +4321,7 @@ dependencies = [
"servo-media",
"servo-media-dummy",
"servo-media-gstreamer",
+ "servo-tracing",
"servo_allocator",
"servo_config",
"servo_geometry",
@@ -6134,7 +6135,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -6735,6 +6736,16 @@ dependencies = [
]
[[package]]
+name = "servo-tracing"
+version = "0.0.1"
+dependencies = [
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "servo_allocator"
version = "0.0.1"
dependencies = [
@@ -6891,6 +6902,7 @@ dependencies = [
"raw-window-handle",
"rustls",
"serde_json",
+ "servo-tracing",
"servo_allocator",
"shellwords",
"sig",
@@ -7475,7 +7487,7 @@ dependencies = [
"getrandom",
"once_cell",
"rustix",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index eb83cd3dfa2..9edae9c058b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -125,6 +125,7 @@ serde_json = "1.0"
servo-media = { git = "https://github.com/servo/media" }
servo-media-dummy = { git = "https://github.com/servo/media" }
servo-media-gstreamer = { git = "https://github.com/servo/media" }
+servo-tracing = { path = "components/servo_tracing" }
servo_arc = { git = "https://github.com/servo/stylo", branch = "2025-03-15" }
smallbitvec = "2.6.0"
smallvec = "1.15"
diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs
index fe961a299a1..3f70b0abb89 100644
--- a/components/constellation/constellation.rs
+++ b/components/constellation/constellation.rs
@@ -973,7 +973,6 @@ where
event_loop,
load_data,
prev_throttled: throttled,
- webrender_document: self.webrender_document,
webgl_chan: self
.webgl_threads
.as_ref()
diff --git a/components/constellation/pipeline.rs b/components/constellation/pipeline.rs
index b6e546acd48..2e139578ffe 100644
--- a/components/constellation/pipeline.rs
+++ b/components/constellation/pipeline.rs
@@ -47,7 +47,6 @@ use serde::{Deserialize, Serialize};
use servo_config::opts::{self, Opts};
use servo_config::prefs::{self, Preferences};
use servo_url::ServoUrl;
-use webrender_api::DocumentId;
use crate::event_loop::EventLoop;
use crate::process_manager::Process;
@@ -184,9 +183,6 @@ pub struct InitialPipelineState {
/// compositor threads after spawning a pipeline.
pub prev_throttled: bool,
- /// The ID of the document processed by this script thread.
- pub webrender_document: DocumentId,
-
/// A channel to the WebGL thread.
pub webgl_chan: Option<WebGLPipeline>,
@@ -288,7 +284,6 @@ impl Pipeline {
opts: (*opts::get()).clone(),
prefs: Box::new(prefs::get().clone()),
pipeline_namespace_id: state.pipeline_namespace_id,
- webrender_document: state.webrender_document,
cross_process_compositor_api: state
.compositor_proxy
.cross_process_compositor_api
@@ -503,7 +498,6 @@ pub struct UnprivilegedPipelineContent {
prefs: Box<Preferences>,
pipeline_namespace_id: PipelineNamespaceId,
cross_process_compositor_api: CrossProcessCompositorApi,
- webrender_document: DocumentId,
webgl_chan: Option<WebGLPipeline>,
webxr_registry: Option<webxr_api::Registry>,
player_context: WindowGLContext,
@@ -551,7 +545,6 @@ impl UnprivilegedPipelineContent {
content_process_shutdown_sender: content_process_shutdown_chan,
webgl_chan: self.webgl_chan,
webxr_registry: self.webxr_registry,
- webrender_document: self.webrender_document,
compositor_api: self.cross_process_compositor_api.clone(),
player_context: self.player_context.clone(),
inherited_secure_context: self.load_data.inherited_secure_context,
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 0308e207e65..96176132b6b 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -83,8 +83,8 @@ use style::stylesheets::UrlExtraData;
use style_traits::CSSPixel;
use stylo_atoms::Atom;
use url::Position;
+use webrender_api::ExternalScrollId;
use webrender_api::units::{DevicePixel, LayoutPixel};
-use webrender_api::{DocumentId, ExternalScrollId};
use super::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use super::bindings::trace::HashMapTracedValues;
@@ -353,10 +353,6 @@ pub(crate) struct Window {
test_worklet: MutNullableDom<Worklet>,
/// <https://drafts.css-houdini.org/css-paint-api-1/#paint-worklet>
paint_worklet: MutNullableDom<Worklet>,
- /// The Webrender Document id associated with this window.
- #[ignore_malloc_size_of = "defined in webrender_api"]
- #[no_trace]
- webrender_document: DocumentId,
/// Flag to identify whether mutation observers are present(true)/absent(false)
exists_mut_observer: Cell<bool>,
@@ -2775,10 +2771,6 @@ impl Window {
.unwrap();
}
- pub(crate) fn webrender_document(&self) -> DocumentId {
- self.webrender_document
- }
-
#[cfg(feature = "webxr")]
pub(crate) fn in_immersive_xr_session(&self) -> bool {
self.navigator
@@ -2821,7 +2813,6 @@ impl Window {
webgl_chan: Option<WebGLChan>,
#[cfg(feature = "webxr")] webxr_registry: Option<webxr_api::Registry>,
microtask_queue: Rc<MicrotaskQueue>,
- webrender_document: DocumentId,
compositor_api: CrossProcessCompositorApi,
relayout_event: bool,
unminify_js: bool,
@@ -2906,7 +2897,6 @@ impl Window {
local_script_source,
test_worklet: Default::default(),
paint_worklet: Default::default(),
- webrender_document,
exists_mut_observer: Cell::new(false),
compositor_api,
has_sent_idle_message: Cell::new(false),
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index da37a12c8a7..c9b27bb6c56 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -98,7 +98,6 @@ use timers::{TimerEventRequest, TimerScheduler};
use url::Position;
#[cfg(feature = "webgpu")]
use webgpu_traits::{WebGPUDevice, WebGPUMsg};
-use webrender_api::DocumentId;
use webrender_api::units::DevicePixel;
use crate::document_collection::DocumentCollection;
@@ -284,10 +283,6 @@ pub struct ScriptThread {
/// <https://html.spec.whatwg.org/multipage/#custom-element-reactions-stack>
custom_element_reaction_stack: CustomElementReactionStack,
- /// The Webrender Document ID associated with this thread.
- #[no_trace]
- webrender_document: DocumentId,
-
/// Cross-process access to the compositor's API.
#[no_trace]
compositor_api: CrossProcessCompositorApi,
@@ -938,7 +933,6 @@ impl ScriptThread {
worklet_thread_pool: Default::default(),
docs_with_no_blocking_loads: Default::default(),
custom_element_reaction_stack: CustomElementReactionStack::new(),
- webrender_document: state.webrender_document,
compositor_api: state.compositor_api,
profile_script_events: opts.debug.profile_script_events,
print_pwm: opts.print_pwm,
@@ -3136,7 +3130,6 @@ impl ScriptThread {
#[cfg(feature = "webxr")]
self.webxr_registry.clone(),
self.microtask_queue.clone(),
- self.webrender_document,
self.compositor_api.clone(),
self.relayout_event,
self.unminify_js,
diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml
index 0c4eaf40904..498d170492d 100644
--- a/components/servo/Cargo.toml
+++ b/components/servo/Cargo.toml
@@ -104,6 +104,7 @@ serde = { workspace = true }
servo-media = { workspace = true }
servo-media-dummy = { workspace = true }
servo-media-gstreamer = { workspace = true, optional = true }
+servo-tracing = { workspace = true }
servo_allocator = { path = "../allocator" }
servo_config = { path = "../config" }
servo_geometry = { path = "../geometry" }
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index be56ffd5c1f..7fb990527ec 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -246,10 +246,7 @@ impl webrender_api::RenderNotifier for RenderNotifier {
}
impl Servo {
- #[cfg_attr(
- feature = "tracing",
- tracing::instrument(skip(builder), fields(servo_profiling = true), level = "trace",)
- )]
+ #[servo_tracing::instrument(skip(builder))]
fn new(builder: ServoBuilder) -> Self {
// Global configuration options, parsed from the command line.
let opts = builder.opts.map(|opts| *opts);
diff --git a/components/servo_tracing/Cargo.toml b/components/servo_tracing/Cargo.toml
new file mode 100644
index 00000000000..1660aa7f691
--- /dev/null
+++ b/components/servo_tracing/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "servo-tracing"
+edition.workspace = true
+version.workspace = true
+authors.workspace = true
+license.workspace = true
+publish.workspace = true
+rust-version.workspace = true
+
+[dependencies]
+quote = { workspace = true }
+proc-macro2 = { workspace = true }
+syn = { version = "2", features = ["full"] }
+
+[lib]
+path = "lib.rs"
+proc-macro = true
+doctest = false
+
+[dev-dependencies]
+prettyplease = "0.2.32"
diff --git a/components/servo_tracing/lib.rs b/components/servo_tracing/lib.rs
new file mode 100644
index 00000000000..04e87ee6cc0
--- /dev/null
+++ b/components/servo_tracing/lib.rs
@@ -0,0 +1,394 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * 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/. */
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+use proc_macro2::Punct;
+use quote::{ToTokens, TokenStreamExt, quote};
+use syn::parse::{Parse, Parser};
+use syn::punctuated::Punctuated;
+use syn::token::Comma;
+use syn::{Expr, ItemFn, Meta, MetaList, Token, parse_quote, parse2};
+
+struct Fields(MetaList);
+impl From<MetaList> for Fields {
+ fn from(value: MetaList) -> Self {
+ Fields(value)
+ }
+}
+
+impl Fields {
+ fn create_with_servo_profiling() -> Self {
+ Fields(parse_quote! { fields(servo_profiling = true) })
+ }
+
+ fn inject_servo_profiling(&mut self) -> syn::Result<()> {
+ let metalist = std::mem::replace(&mut self.0, parse_quote! {field()});
+
+ let arguments: Punctuated<Meta, Comma> =
+ Punctuated::parse_terminated.parse2(metalist.tokens)?;
+
+ let servo_profile_given = arguments
+ .iter()
+ .any(|arg| arg.path().is_ident("servo_profiling"));
+
+ let metalist = if servo_profile_given {
+ parse_quote! {
+ fields(#arguments)
+ }
+ } else {
+ parse_quote! {
+ fields(servo_profiling=true, #arguments)
+ }
+ };
+
+ let _ = std::mem::replace(&mut self.0, metalist);
+
+ Ok(())
+ }
+}
+
+impl ToTokens for Fields {
+ fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+ let items = &self.0;
+ tokens.append_all(quote! { #items });
+ }
+}
+enum Directive {
+ Passthrough(Meta),
+ Level(Expr),
+ Fields(Fields),
+}
+
+impl From<Fields> for Directive {
+ fn from(value: Fields) -> Self {
+ Directive::Fields(value)
+ }
+}
+
+impl Directive {
+ fn is_level(&self) -> bool {
+ matches!(self, Directive::Level(..))
+ }
+
+ fn fields_mut(&mut self) -> Option<&mut Fields> {
+ match self {
+ Directive::Fields(fields) => Some(fields),
+ _ => None,
+ }
+ }
+}
+
+impl ToTokens for Directive {
+ fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+ match self {
+ Directive::Passthrough(meta) => tokens.append_all(quote! { #meta }),
+ Directive::Level(level) => tokens.append_all(quote! { level = #level }),
+ Directive::Fields(fields) => tokens.append_all(quote! { #fields }),
+ };
+ }
+}
+
+impl ToTokens for InstrumentConfiguration {
+ fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
+ tokens.append_terminated(&self.0, Punct::new(',', proc_macro2::Spacing::Joint));
+ }
+}
+
+struct InstrumentConfiguration(Vec<Directive>);
+
+impl InstrumentConfiguration {
+ fn inject_servo_profiling(&mut self) -> syn::Result<()> {
+ let fields = self.0.iter_mut().find_map(Directive::fields_mut);
+ match fields {
+ None => {
+ self.0
+ .push(Directive::from(Fields::create_with_servo_profiling()));
+ Ok(())
+ },
+ Some(fields) => fields.inject_servo_profiling(),
+ }
+ }
+
+ fn inject_level(&mut self) {
+ if self.0.iter().any(|a| a.is_level()) {
+ return;
+ }
+ self.0.push(Directive::Level(parse_quote! { "trace" }));
+ }
+}
+
+impl Parse for InstrumentConfiguration {
+ fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
+ let args = Punctuated::<Meta, Token![,]>::parse_terminated(input)?;
+ let mut components = vec![];
+
+ for arg in args {
+ match arg {
+ Meta::List(meta_list) if meta_list.path.is_ident("fields") => {
+ components.push(Directive::Fields(meta_list.into()));
+ },
+ Meta::NameValue(meta_name_value) if meta_name_value.path.is_ident("level") => {
+ components.push(Directive::Level(meta_name_value.value));
+ },
+ _ => {
+ components.push(Directive::Passthrough(arg));
+ },
+ }
+ }
+ Ok(InstrumentConfiguration(components))
+ }
+}
+
+fn instrument_internal(
+ attr: proc_macro2::TokenStream,
+ item: proc_macro2::TokenStream,
+) -> syn::Result<proc_macro2::TokenStream> {
+ // Prepare passthrough arguments for tracing::instrument
+ let mut configuration: InstrumentConfiguration = parse2(attr)?;
+ let input_fn: ItemFn = parse2(item)?;
+
+ configuration.inject_servo_profiling()?;
+ configuration.inject_level();
+
+ let output = quote! {
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument(
+ #configuration
+ )
+ )]
+ #input_fn
+ };
+
+ Ok(output)
+}
+
+#[proc_macro_attribute]
+/// Instruments a function with some sane defaults by automatically:
+/// - setting the attribute behind the "tracing" flag
+/// - adding `servo_profiling = true` in the `tracing::instrument(fields(...))` argument.
+/// - setting `level = "trace"` if it is not given.
+///
+/// This macro assumes the consuming crate has a `tracing` feature flag.
+///
+/// We need to be able to set the following
+/// ```
+/// #[cfg_attr(
+/// feature = "tracing",
+/// tracing::instrument(
+/// name = "MyCustomName",
+/// skip_all,
+/// fields(servo_profiling = true),
+/// level = "trace",
+/// )
+/// )]
+/// fn my_fn() { /* .... */ }
+/// ```
+/// from a simpler macro, such as:
+///
+/// ```
+/// #[servo_tracing::instrument(name = "MyCustomName", skip_all)]
+/// fn my_fn() { /* .... */ }
+/// ```
+pub fn instrument(attr: TokenStream, item: TokenStream) -> TokenStream {
+ match instrument_internal(attr.into(), item.into()) {
+ Ok(stream) => stream.into(),
+ Err(err) => err.to_compile_error().into(),
+ }
+}
+
+#[cfg(test)]
+mod test {
+ use proc_macro2::TokenStream;
+ use quote::{ToTokens, quote};
+ use syn::{Attribute, ItemFn};
+
+ use crate::instrument_internal;
+
+ fn extract_instrument_attribute(item_fn: &mut ItemFn) -> TokenStream {
+ let attr: &Attribute = item_fn
+ .attrs
+ .iter()
+ .find(|attr| {
+ // because this is a very nested structure, it is easier to check
+ // by constructing the full path, and then doing a string comparison.
+ let p = attr.path().to_token_stream().to_string();
+ p == "servo_tracing :: instrument"
+ })
+ .expect("Attribute `servo_tracing::instrument` not found");
+
+ // we create a tokenstream of the actual internal contents of the attribute
+ let attr_args = attr
+ .parse_args::<TokenStream>()
+ .expect("Failed to parse attribute args");
+
+ // we remove the tracing attribute, this is to avoid passing it as an actual attribute to itself.
+ item_fn.attrs.retain(|attr| {
+ attr.path().to_token_stream().to_string() != "servo_tracing :: instrument"
+ });
+
+ attr_args
+ }
+
+ /// To make test case generation easy, we parse a test_case as a function item
+ /// with its own attributes, including [`servo_tracing::instrument`].
+ ///
+ /// We extract the [`servo_tracing::instrument`] attribute, and pass it as the first argument to
+ /// [`servo_tracing::instrument_internal`],
+ fn evaluate(function: TokenStream, test_case: TokenStream, expected: TokenStream) {
+ let test_case = quote! {
+ #test_case
+ #function
+ };
+ let expected = quote! {
+ #expected
+ #function
+ };
+ let function_str = function.to_string();
+ let function_str = syn::parse_file(&function_str).expect("function to have valid syntax");
+ let function_str = prettyplease::unparse(&function_str);
+
+ let mut item_fn: ItemFn =
+ syn::parse2(test_case).expect("Failed to parse input as function");
+
+ let attr_args = extract_instrument_attribute(&mut item_fn);
+ let item_fn = item_fn.to_token_stream();
+
+ let generated = instrument_internal(attr_args, item_fn).expect("Generation to not fail.");
+
+ let generated = syn::parse_file(generated.to_string().as_str())
+ .expect("to have generated a valid function");
+ let generated = prettyplease::unparse(&generated);
+ let expected = syn::parse_file(expected.to_string().as_str())
+ .expect("to have been given a valid expected function");
+ let expected = prettyplease::unparse(&expected);
+
+ eprintln!(
+ "Generated:---------:\n{}--------\nExpected:----------\n{}",
+ &generated, &expected
+ );
+ assert_eq!(generated, expected);
+ assert!(
+ generated.contains(&function_str),
+ "Expected generated code: {generated} to contain the function code: {function_str}"
+ );
+ }
+
+ fn function1() -> TokenStream {
+ quote! {
+ pub fn start(
+ state: (),
+ layout_factory: (),
+ random_pipeline_closure_probability: (),
+ random_pipeline_closure_seed: (),
+ hard_fail: (),
+ canvas_create_sender: (),
+ canvas_ipc_sender: (),
+ ) {
+ }
+ }
+ }
+
+ fn function2() -> TokenStream {
+ quote! {
+ fn layout(
+ mut self,
+ layout_context: &LayoutContext,
+ positioning_context: &mut PositioningContext,
+ containing_block_for_children: &ContainingBlock,
+ containing_block_for_table: &ContainingBlock,
+ depends_on_block_constraints: bool,
+ ) {
+ }
+ }
+ }
+
+ #[test]
+ fn passing_servo_profiling_and_level_and_aux() {
+ let function = function1();
+ let expected = quote! {
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument(skip(state, layout_factory), fields(servo_profiling = true), level = "trace",)
+ )]
+ };
+
+ let test_case = quote! {
+ #[servo_tracing::instrument(skip(state, layout_factory),fields(servo_profiling = true),level = "trace",)]
+ };
+
+ evaluate(function, test_case, expected);
+ }
+
+ #[test]
+ fn passing_servo_profiling_and_level() {
+ let function = function1();
+ let expected = quote! {
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument( fields(servo_profiling = true), level = "trace",)
+ )]
+ };
+
+ let test_case = quote! {
+ #[servo_tracing::instrument(fields(servo_profiling = true),level = "trace",)]
+ };
+ evaluate(function, test_case, expected);
+ }
+
+ #[test]
+ fn passing_servo_profiling() {
+ let function = function1();
+ let expected = quote! {
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument( fields(servo_profiling = true), level = "trace",)
+ )]
+ };
+
+ let test_case = quote! {
+ #[servo_tracing::instrument(fields(servo_profiling = true))]
+ };
+ evaluate(function, test_case, expected);
+ }
+
+ #[test]
+ fn inject_level_and_servo_profiling() {
+ let function = function1();
+ let expected = quote! {
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument(fields(servo_profiling = true), level = "trace",)
+ )]
+ };
+
+ let test_case = quote! {
+ #[servo_tracing::instrument()]
+ };
+ evaluate(function, test_case, expected);
+ }
+
+ #[test]
+ fn instrument_with_name() {
+ let function = function2();
+ let expected = quote! {
+ #[cfg_attr(
+ feature = "tracing",
+ tracing::instrument(
+ name = "Table::layout",
+ skip_all,
+ fields(servo_profiling = true),
+ level = "trace",
+ )
+ )]
+ };
+
+ let test_case = quote! {
+ #[servo_tracing::instrument(name="Table::layout", skip_all)]
+ };
+
+ evaluate(function, test_case, expected);
+ }
+}
diff --git a/components/shared/script/lib.rs b/components/shared/script/lib.rs
index 8b05cabd64e..a39be739fd5 100644
--- a/components/shared/script/lib.rs
+++ b/components/shared/script/lib.rs
@@ -47,8 +47,8 @@ use style_traits::{CSSPixel, SpeculativePainter};
use stylo_atoms::Atom;
#[cfg(feature = "webgpu")]
use webgpu_traits::WebGPUMsg;
+use webrender_api::ImageKey;
use webrender_api::units::DevicePixel;
-use webrender_api::{DocumentId, ImageKey};
/// The initial data required to create a new layout attached to an existing script thread.
#[derive(Debug, Deserialize, Serialize)]
@@ -318,8 +318,6 @@ pub struct InitialScriptState {
pub webgl_chan: Option<WebGLPipeline>,
/// The XR device registry
pub webxr_registry: Option<webxr_api::Registry>,
- /// The Webrender document ID associated with this thread.
- pub webrender_document: DocumentId,
/// Access to the compositor across a process boundary.
pub compositor_api: CrossProcessCompositorApi,
/// Application window's GL Context for Media player
diff --git a/ports/servoshell/Cargo.toml b/ports/servoshell/Cargo.toml
index a5d3a52aefd..ed3a340e8d4 100644
--- a/ports/servoshell/Cargo.toml
+++ b/ports/servoshell/Cargo.toml
@@ -68,6 +68,7 @@ mime_guess = { workspace = true }
url = { workspace = true }
raw-window-handle = { workspace = true }
rustls = { workspace = true, features = ["aws-lc-rs"] }
+servo-tracing = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true, optional = true }
tracing-subscriber = { workspace = true, optional = true, features = ["env-filter"] }