Skip to content

[cppjit] Remember templated names resolved by interop::GetScope - #23801

Closed
jmcarcell wants to merge 1 commit into
root-project:masterfrom
jmcarcell:cppjit-getscope-template-cache
Closed

jmcarcell wants to merge 1 commit into
root-project:masterfrom
jmcarcell:cppjit-getscope-template-cache

Conversation

@jmcarcell

Copy link
Copy Markdown
Contributor

This Pull request:

Binding an object to a templated class by name, for example cppjit.bind_object(addr, "std::vector<double>"), which TDirectoryFile.Get does for every object it returns, grows the memory by about 11 kB on every call. This doesn't happen with ROOT 6.40:

vector<double>         RSS growth after 2000 bind_object calls: 23772 kB
std::vector<double>    RSS growth after 2000 bind_object calls: 25268 kB
TGraph                 RSS growth after 2000 bind_object calls: 0 kB
TH1F                   RSS growth after 2000 bind_object calls: 0 kB

Changes or fixes:

interop::GetScope doesn't remember what a templated name resolved to, so every lookup of the same name repeats this:

  • AppendTypesSlow declares a new __cppjit_interop_sN variable in the interpreter to resolve the name. This is most of the growth.
  • Before that, Cpp::GetScope fails on the name. The failed lookup makes TClingCallbacks::LookupObject try to autoload it, and TCling::GetClassSharedLibs parses the name again with cling::LookupHelper::findScope. For std::vector<double> this adds new AST nodes, about 350 B per call (found with heaptrack).

This PR caches successful lookups of templated names at the start of interop::GetScope, so both are skipped. Failed lookups aren't cached because they may succeed once more declarations are available. With the change, the growth after 20000 calls is 0 kB for both vector<double> and std::vector<double>.

compiler-research/cppjit#155 is related, but it doesn't fully fix this issue. It memoizes the result inside AppendTypesSlow, which removes the new variable on every call, including for the other callers of AppendTypesSlow such as overload ranking. However, the failing Cpp::GetScope and the autoload happen before AppendTypesSlow is called. Caching at that later point, which I tried first, still leaves std::vector<double> growing by a few hundred bytes per call. The two changes are complementary. The same interop::GetScope code is also in cppjit's main branch, without the ROOT-specific autoload part.

The new test test57_repeated_template_scope_lookup fails without the change (the memory grows by 25 MB with a threshold of 8 MB) and passes with it.

Checklist:

  • tested changes locally
  • updated the docs (if necessary)

Tested on AlmaLinux 9 with the dev3 view (gcc 16): all 26 cppjit test files pass through ctest.

@jmcarcell

Copy link
Copy Markdown
Contributor Author

Wrong repo

@jmcarcell jmcarcell closed this Oct 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant