diff --git a/components/script/dom/bindings/settings_stack.rs b/components/script/dom/bindings/settings_stack.rs index 0e913eb3de6..7cd157a612f 100644 --- a/components/script/dom/bindings/settings_stack.rs +++ b/components/script/dom/bindings/settings_stack.rs @@ -42,6 +42,8 @@ pub fn is_execution_stack_empty() -> bool { /// RAII struct that pushes and pops entries from the script settings stack. pub struct AutoEntryScript { global: DomRoot, + #[cfg(feature = "tracing")] + span: tracing::span::EnteredSpan, } impl AutoEntryScript { @@ -56,6 +58,8 @@ impl AutoEntryScript { }); AutoEntryScript { global: DomRoot::from_ref(global), + #[cfg(feature = "tracing")] + span: tracing::info_span!("ScriptEvaluate", servo_profiling = true).entered(), } }) } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index ca5d66deb94..ac6a2b07b1e 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -52,7 +52,7 @@ use net_traits::{ fetch_async, CoreResourceMsg, CoreResourceThread, FetchResponseListener, IpcSend, ReferrerPolicy, ResourceThreads, }; -use profile_traits::{ipc as profile_ipc, mem as profile_mem, time as profile_time, time_profile}; +use profile_traits::{ipc as profile_ipc, mem as profile_mem, time as profile_time}; use script_traits::serializable::{BlobData, BlobImpl, FileBlob}; use script_traits::transferable::MessagePortImpl; use script_traits::{ @@ -2677,98 +2677,82 @@ impl GlobalScope { script_base_url: ServoUrl, can_gc: CanGc, ) -> bool { - let metadata = profile_time::TimerMetadata { - url: if filename.is_empty() { - self.get_url().as_str().into() - } else { - filename.into() - }, - iframe: profile_time::TimerMetadataFrameType::RootWindow, - incremental: profile_time::TimerMetadataReflowType::FirstReflow, - }; - time_profile!( - profile_time::ProfilerCategory::ScriptEvaluate, - Some(metadata), - self.time_profiler_chan().clone(), - || { - let cx = GlobalScope::get_cx(); + let cx = GlobalScope::get_cx(); - let ar = enter_realm(self); + let ar = enter_realm(self); - let _aes = AutoEntryScript::new(self); + let _aes = AutoEntryScript::new(self); - unsafe { - rooted!(in(*cx) let mut compiled_script = std::ptr::null_mut::()); - match code { - SourceCode::Text(text_code) => { - let options = CompileOptionsWrapper::new(*cx, filename, line_number); + unsafe { + rooted!(in(*cx) let mut compiled_script = std::ptr::null_mut::()); + match code { + SourceCode::Text(text_code) => { + let options = CompileOptionsWrapper::new(*cx, filename, line_number); - debug!("compiling dom string"); - compiled_script.set(Compile1( - *cx, - options.ptr, - &mut transform_str_to_source_text(text_code), - )); + debug!("compiling dom string"); + compiled_script.set(Compile1( + *cx, + options.ptr, + &mut transform_str_to_source_text(text_code), + )); - if compiled_script.is_null() { - debug!("error compiling Dom string"); - report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc); - return false; - } - }, - SourceCode::Compiled(pre_compiled_script) => { - let options = InstantiateOptions { - skipFilenameValidation: false, - hideScriptFromDebugger: false, - deferDebugMetadata: false, - }; - let script = InstantiateGlobalStencil( - *cx, - &options, - *pre_compiled_script.source_code, - ptr::null_mut(), - ); - compiled_script.set(script); - }, - }; - - assert!(!compiled_script.is_null()); - - rooted!(in(*cx) let mut script_private = UndefinedValue()); - JS_GetScriptPrivate(*compiled_script, script_private.handle_mut()); - - // When `ScriptPrivate` for the compiled script is undefined, - // we need to set it so that it can be used in dynamic import context. - if script_private.is_undefined() { - debug!("Set script private for {}", script_base_url); - - let module_script_data = Rc::new(ModuleScript::new( - script_base_url, - fetch_options, - // We can't initialize an module owner here because - // the executing context of script might be different - // from the dynamic import script's executing context. - None, - )); - - SetScriptPrivate( - *compiled_script, - &PrivateValue(Rc::into_raw(module_script_data) as *const _), - ); - } - - let result = JS_ExecuteScript(*cx, compiled_script.handle(), rval); - - if !result { - debug!("error evaluating Dom string"); + if compiled_script.is_null() { + debug!("error compiling Dom string"); report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc); + return false; } + }, + SourceCode::Compiled(pre_compiled_script) => { + let options = InstantiateOptions { + skipFilenameValidation: false, + hideScriptFromDebugger: false, + deferDebugMetadata: false, + }; + let script = InstantiateGlobalStencil( + *cx, + &options, + *pre_compiled_script.source_code, + ptr::null_mut(), + ); + compiled_script.set(script); + }, + }; - maybe_resume_unwind(); - result - } - }, - ) + assert!(!compiled_script.is_null()); + + rooted!(in(*cx) let mut script_private = UndefinedValue()); + JS_GetScriptPrivate(*compiled_script, script_private.handle_mut()); + + // When `ScriptPrivate` for the compiled script is undefined, + // we need to set it so that it can be used in dynamic import context. + if script_private.is_undefined() { + debug!("Set script private for {}", script_base_url); + + let module_script_data = Rc::new(ModuleScript::new( + script_base_url, + fetch_options, + // We can't initialize an module owner here because + // the executing context of script might be different + // from the dynamic import script's executing context. + None, + )); + + SetScriptPrivate( + *compiled_script, + &PrivateValue(Rc::into_raw(module_script_data) as *const _), + ); + } + + let result = JS_ExecuteScript(*cx, compiled_script.handle(), rval); + + if !result { + debug!("error evaluating Dom string"); + report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc); + } + + maybe_resume_unwind(); + result + } } /// diff --git a/components/shared/profile/time.rs b/components/shared/profile/time.rs index f30ee4a323d..ef36478e9ea 100644 --- a/components/shared/profile/time.rs +++ b/components/shared/profile/time.rs @@ -78,7 +78,11 @@ pub enum ProfilerCategory { ScriptDevtoolsMsg = 0x62, ScriptDocumentEvent = 0x63, ScriptDomEvent = 0x64, + + /// Rust tracing only: the script thread is executing a script. + /// This may include time doing layout or parse work initiated by the script. ScriptEvaluate = 0x65, + ScriptEvent = 0x66, ScriptFileRead = 0x67, ScriptImageCacheMsg = 0x68,