Added function name in timing func call & more span

This commit is contained in:
Dherse 2025-03-30 12:54:15 +02:00
parent c97ce11dbb
commit d735e2ff70
5 changed files with 45 additions and 10 deletions

View File

@ -298,7 +298,12 @@ impl Func {
} }
/// Non-generic implementation of `call`. /// Non-generic implementation of `call`.
#[typst_macros::time(name = "func call", span = self.span(), callsite = args.span)] #[typst_macros::time(
name = "func call",
span = self.span(),
callsite = args.span,
func = self.name().unwrap_or("anonymous")
)]
fn call_impl( fn call_impl(
&self, &self,
engine: &mut Engine, engine: &mut Engine,

View File

@ -16,6 +16,7 @@ pub struct Meta {
pub span: Option<syn::Expr>, pub span: Option<syn::Expr>,
pub callsite: Option<syn::Expr>, pub callsite: Option<syn::Expr>,
pub name: Option<String>, pub name: Option<String>,
pub func: Option<syn::Expr>,
} }
impl Parse for Meta { impl Parse for Meta {
@ -24,15 +25,28 @@ impl Parse for Meta {
name: parse_string::<kw::name>(input)?, name: parse_string::<kw::name>(input)?,
span: parse_key_value::<kw::span, syn::Expr>(input)?, span: parse_key_value::<kw::span, syn::Expr>(input)?,
callsite: parse_key_value::<kw::callsite, syn::Expr>(input)?, callsite: parse_key_value::<kw::callsite, syn::Expr>(input)?,
func: parse_key_value::<kw::func, syn::Expr>(input)?,
}) })
} }
} }
fn create(meta: Meta, mut item: syn::ItemFn) -> Result<TokenStream> { fn create(meta: Meta, mut item: syn::ItemFn) -> Result<TokenStream> {
let name = meta.name.unwrap_or_else(|| item.sig.ident.to_string()); let name = meta.name.unwrap_or_else(|| item.sig.ident.to_string());
let func = match meta.func {
Some(func) => {
if meta.callsite.is_none() {
bail!(func, "the `func` argument can only be used with a callsite")
}
quote! { Some(#func.into()) }
}
None => quote! { None },
};
let construct = match (meta.span.as_ref(), meta.callsite.as_ref()) { let construct = match (meta.span.as_ref(), meta.callsite.as_ref()) {
(Some(span), Some(callsite)) => quote! { (Some(span), Some(callsite)) => quote! {
with_callsite(#name, Some(#span.into_raw()), Some(#callsite.into_raw())) with_callsite(#name, Some(#span.into_raw()), Some(#callsite.into_raw()), #func)
}, },
(Some(span), None) => quote! { (Some(span), None) => quote! {
with_span(#name, Some(#span.into_raw())) with_span(#name, Some(#span.into_raw()))

View File

@ -255,6 +255,7 @@ pub mod kw {
syn::custom_keyword!(name); syn::custom_keyword!(name);
syn::custom_keyword!(span); syn::custom_keyword!(span);
syn::custom_keyword!(callsite); syn::custom_keyword!(callsite);
syn::custom_keyword!(func);
syn::custom_keyword!(title); syn::custom_keyword!(title);
syn::custom_keyword!(scope); syn::custom_keyword!(scope);
syn::custom_keyword!(contextual); syn::custom_keyword!(contextual);

View File

@ -34,7 +34,7 @@ use typst_syntax::Span;
use typst_utils::{SliceExt, SmallBitSet}; use typst_utils::{SliceExt, SmallBitSet};
/// Realize content into a flat list of well-known, styled items. /// Realize content into a flat list of well-known, styled items.
#[typst_macros::time(name = "realize")] #[typst_macros::time(name = "realize", span = content.span())]
pub fn realize<'a>( pub fn realize<'a>(
kind: RealizationKind, kind: RealizationKind,
engine: &mut Engine, engine: &mut Engine,

View File

@ -93,21 +93,23 @@ pub fn export_json<W: Write>(
mut source: impl FnMut(NonZeroU64) -> (String, u32), mut source: impl FnMut(NonZeroU64) -> (String, u32),
) -> Result<(), String> { ) -> Result<(), String> {
#[derive(Serialize)] #[derive(Serialize)]
struct Entry { struct Entry<'a> {
name: &'static str, name: &'static str,
cat: &'static str, cat: &'static str,
ph: &'static str, ph: &'static str,
ts: f64, ts: f64,
pid: u64, pid: u64,
tid: u64, tid: u64,
args: Option<Args>, args: Option<Args<'a>>,
} }
#[derive(Serialize)] #[derive(Serialize)]
struct Args { struct Args<'a> {
file: String, file: String,
line: u32, line: u32,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
function_name: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
callsite_file: Option<String>, callsite_file: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
callsite_line: Option<u32>, callsite_line: Option<u32>,
@ -139,7 +141,13 @@ pub fn export_json<W: Write>(
None => (None, None), None => (None, None),
}; };
Args { file, line, callsite_file, callsite_line } Args {
file,
line,
callsite_file,
callsite_line,
function_name: event.func.as_deref(),
}
}), }),
}) })
.map_err(|e| format!("failed to serialize event: {e}"))?; .map_err(|e| format!("failed to serialize event: {e}"))?;
@ -155,6 +163,7 @@ pub struct TimingScope {
name: &'static str, name: &'static str,
span: Option<NonZeroU64>, span: Option<NonZeroU64>,
callsite: Option<NonZeroU64>, callsite: Option<NonZeroU64>,
func: Option<String>,
thread_id: u64, thread_id: u64,
} }
@ -172,7 +181,7 @@ impl TimingScope {
/// `typst-timing`). /// `typst-timing`).
#[inline] #[inline]
pub fn with_span(name: &'static str, span: Option<NonZeroU64>) -> Option<Self> { pub fn with_span(name: &'static str, span: Option<NonZeroU64>) -> Option<Self> {
Self::with_callsite(name, span, None) Self::with_callsite(name, span, None, None)
} }
/// Create a new scope with a span if timing is enabled. /// Create a new scope with a span if timing is enabled.
@ -185,9 +194,10 @@ impl TimingScope {
name: &'static str, name: &'static str,
span: Option<NonZeroU64>, span: Option<NonZeroU64>,
callsite: Option<NonZeroU64>, callsite: Option<NonZeroU64>,
func: Option<String>,
) -> Option<Self> { ) -> Option<Self> {
if is_enabled() { if is_enabled() {
return Some(Self::new_impl(name, span, callsite)); return Some(Self::new_impl(name, span, callsite, func));
} }
None None
} }
@ -197,6 +207,7 @@ impl TimingScope {
name: &'static str, name: &'static str,
span: Option<NonZeroU64>, span: Option<NonZeroU64>,
callsite: Option<NonZeroU64>, callsite: Option<NonZeroU64>,
func: Option<String>,
) -> Self { ) -> Self {
let (thread_id, timestamp) = let (thread_id, timestamp) =
THREAD_DATA.with(|data| (data.id, Timestamp::now_with(data))); THREAD_DATA.with(|data| (data.id, Timestamp::now_with(data)));
@ -206,9 +217,10 @@ impl TimingScope {
name, name,
span, span,
callsite, callsite,
func: func.clone(),
thread_id, thread_id,
}); });
Self { name, span, callsite: None, thread_id } Self { name, span, callsite: None, thread_id, func }
} }
} }
@ -222,6 +234,7 @@ impl Drop for TimingScope {
span: self.span, span: self.span,
callsite: self.callsite, callsite: self.callsite,
thread_id: self.thread_id, thread_id: self.thread_id,
func: std::mem::take(&mut self.func),
}); });
} }
} }
@ -238,6 +251,8 @@ struct Event {
span: Option<NonZeroU64>, span: Option<NonZeroU64>,
/// The raw value of the callsite span of the code that this event was recorded in. /// The raw value of the callsite span of the code that this event was recorded in.
callsite: Option<NonZeroU64>, callsite: Option<NonZeroU64>,
/// The function being called (if any).
func: Option<String>,
/// The thread ID of this event. /// The thread ID of this event.
thread_id: u64, thread_id: u64,
} }