Re: [PATCH v4 11/23] perf annotate: Move struct annotation to a hashmap and remove symbol_conf.priv_size

From: Namhyung Kim

Date: Sat Nov 14 2026 - 23:06:17 EST


On Fri, Nov 13, 2026 at 09:17:22AM -0800, Ian Rogers wrote:
> Previously, enabling annotation added sizeof(struct annotation) to
> symbol_conf.priv_size, bloating every loaded struct symbol in every DSO
> even though only a small fraction of symbols are ever annotated.
>
> Move struct annotation storage to an on-demand hashmap in
> util/annotate.c keyed by struct symbol pointer, guarded by
> annotations_lock and tracked via a new SYMBOL_FLAG_ANNOTATED flag in
> sym->flags so unannotated symbols pay zero lookup or teardown overhead.
> If allocation fails in symbol__annotation(), return a static
> empty_annotation fallback so callers that do not check for NULL remain
> safe while mutating callers check for &empty_annotation.
>
> With annotation, TUI map browser indices, and db-export symbol IDs no
> longer using negative-offset space ahead of struct symbol, remove
> symbol_conf.priv_size and symbol__priv().
>
> Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
> ---
[SNIP]
> diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
> index 6347bd218ad5..a0ad62e452be 100644
> --- a/tools/perf/util/symbol.h
> +++ b/tools/perf/util/symbol.h
> @@ -78,9 +78,9 @@ enum symbol_idle_kind {
> #define SYMBOL_FLAG_INLINED (1 << 11)
> #define SYMBOL_FLAG_ANNOTATE2 (1 << 12)
> #define SYMBOL_FLAG_IFUNC_ALIAS (1 << 13)
> +#define SYMBOL_FLAG_ANNOTATED (1 << 14)

Do we really need this? I think we can just check the hash table
without adding the flag. Of course it requires a read lock, but
it'll be needed anyway, right?

Thanks,
Namhyung


> /**
> - * A symtab entry. When allocated this may be preceded by an annotation (see
> - * symbol__annotation) and/or a browser_index (see symbol__browser_index).
> + * A symtab entry.
> */
> struct symbol {
> struct rb_node rb_node;
> @@ -135,12 +135,19 @@ static inline bool symbol__ifunc_alias(const struct symbol *sym)
> SYMBOL_FLAG_IFUNC_ALIAS) != 0;
> }
>
> +static inline bool symbol__annotated(const struct symbol *sym)
> +{
> + return (atomic_load_explicit(&sym->flags, memory_order_relaxed) &
> + SYMBOL_FLAG_ANNOTATED) != 0;
> +}
> +
> bool symbol__is_idle(struct symbol *sym, const struct dso *dso, struct perf_env *env);
>
> void symbol__set_ignore(struct symbol *sym, bool ignore);
> void symbol__set_annotate2(struct symbol *sym, bool annotate2);
> void symbol__set_inlined(struct symbol *sym, bool inlined);
> void symbol__set_ifunc_alias(struct symbol *sym, bool ifunc_alias);
> +void symbol__set_annotated(struct symbol *sym, bool annotated);
>
> /* symbols__for_each_entry - iterate over symbols (rb_root)
> *