mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Make ScriptEvaluate count script execution in DOM events and timers (#34286)
Signed-off-by: Delan Azabani <dazabani@igalia.com>
This commit is contained in:
parent
4a06dc53f6
commit
26748621cd
3 changed files with 77 additions and 85 deletions
|
@ -42,6 +42,8 @@ pub fn is_execution_stack_empty() -> bool {
|
||||||
/// RAII struct that pushes and pops entries from the script settings stack.
|
/// RAII struct that pushes and pops entries from the script settings stack.
|
||||||
pub struct AutoEntryScript {
|
pub struct AutoEntryScript {
|
||||||
global: DomRoot<GlobalScope>,
|
global: DomRoot<GlobalScope>,
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
span: tracing::span::EnteredSpan,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AutoEntryScript {
|
impl AutoEntryScript {
|
||||||
|
@ -56,6 +58,8 @@ impl AutoEntryScript {
|
||||||
});
|
});
|
||||||
AutoEntryScript {
|
AutoEntryScript {
|
||||||
global: DomRoot::from_ref(global),
|
global: DomRoot::from_ref(global),
|
||||||
|
#[cfg(feature = "tracing")]
|
||||||
|
span: tracing::info_span!("ScriptEvaluate", servo_profiling = true).entered(),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ use net_traits::{
|
||||||
fetch_async, CoreResourceMsg, CoreResourceThread, FetchResponseListener, IpcSend,
|
fetch_async, CoreResourceMsg, CoreResourceThread, FetchResponseListener, IpcSend,
|
||||||
ReferrerPolicy, ResourceThreads,
|
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::serializable::{BlobData, BlobImpl, FileBlob};
|
||||||
use script_traits::transferable::MessagePortImpl;
|
use script_traits::transferable::MessagePortImpl;
|
||||||
use script_traits::{
|
use script_traits::{
|
||||||
|
@ -2677,98 +2677,82 @@ impl GlobalScope {
|
||||||
script_base_url: ServoUrl,
|
script_base_url: ServoUrl,
|
||||||
can_gc: CanGc,
|
can_gc: CanGc,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let metadata = profile_time::TimerMetadata {
|
let cx = GlobalScope::get_cx();
|
||||||
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 ar = enter_realm(self);
|
let ar = enter_realm(self);
|
||||||
|
|
||||||
let _aes = AutoEntryScript::new(self);
|
let _aes = AutoEntryScript::new(self);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
rooted!(in(*cx) let mut compiled_script = std::ptr::null_mut::<JSScript>());
|
rooted!(in(*cx) let mut compiled_script = std::ptr::null_mut::<JSScript>());
|
||||||
match code {
|
match code {
|
||||||
SourceCode::Text(text_code) => {
|
SourceCode::Text(text_code) => {
|
||||||
let options = CompileOptionsWrapper::new(*cx, filename, line_number);
|
let options = CompileOptionsWrapper::new(*cx, filename, line_number);
|
||||||
|
|
||||||
debug!("compiling dom string");
|
debug!("compiling dom string");
|
||||||
compiled_script.set(Compile1(
|
compiled_script.set(Compile1(
|
||||||
*cx,
|
*cx,
|
||||||
options.ptr,
|
options.ptr,
|
||||||
&mut transform_str_to_source_text(text_code),
|
&mut transform_str_to_source_text(text_code),
|
||||||
));
|
));
|
||||||
|
|
||||||
if compiled_script.is_null() {
|
if compiled_script.is_null() {
|
||||||
debug!("error compiling Dom string");
|
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");
|
|
||||||
report_pending_exception(*cx, true, InRealm::Entered(&ar), can_gc);
|
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();
|
assert!(!compiled_script.is_null());
|
||||||
result
|
|
||||||
}
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#timer-initialisation-steps>
|
/// <https://html.spec.whatwg.org/multipage/#timer-initialisation-steps>
|
||||||
|
|
|
@ -78,7 +78,11 @@ pub enum ProfilerCategory {
|
||||||
ScriptDevtoolsMsg = 0x62,
|
ScriptDevtoolsMsg = 0x62,
|
||||||
ScriptDocumentEvent = 0x63,
|
ScriptDocumentEvent = 0x63,
|
||||||
ScriptDomEvent = 0x64,
|
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,
|
ScriptEvaluate = 0x65,
|
||||||
|
|
||||||
ScriptEvent = 0x66,
|
ScriptEvent = 0x66,
|
||||||
ScriptFileRead = 0x67,
|
ScriptFileRead = 0x67,
|
||||||
ScriptImageCacheMsg = 0x68,
|
ScriptImageCacheMsg = 0x68,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue