Skip to content

feat(jmh-fork): add perf-map JVMTI agent for source-aware JIT symbol resolution#7

Open
not-matthias wants to merge 6 commits intomainfrom
cod-2516-investigate-node-origin-for-java
Open

feat(jmh-fork): add perf-map JVMTI agent for source-aware JIT symbol resolution#7
not-matthias wants to merge 6 commits intomainfrom
cod-2516-investigate-node-origin-for-java

Conversation

@not-matthias
Copy link
Copy Markdown
Member

Key features:

  • Resolves project source files to absolute paths via git root discovery
  • Falls back to clean relative paths for JDK/dependency classes
  • Thread-safe source file cache with pthread_once for git root init

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq bot commented Apr 15, 2026

Merging this PR will degrade performance by 19.51%

⚡ 1 improved benchmark
❌ 3 regressed benchmarks
✅ 121 untouched benchmarks
⏩ 9 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
fibonacciBottomUp[20] 1.4 µs 1.2 µs +15.52%
dualPivotQuickSort[10000] 5.2 ms 6.4 ms -19.51%
shellSort[1000] 163.4 µs 182.6 µs -10.5%
timSort[100] 8.7 µs 10.2 µs -14.81%

Comparing cod-2516-investigate-node-origin-for-java (c7c19aa) with main (8cb09f5)

Open in CodSpeed

Footnotes

  1. 9 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@not-matthias not-matthias force-pushed the cod-2516-investigate-node-origin-for-java branch from 0220c52 to 02a8fe5 Compare April 15, 2026 14:07
@not-matthias not-matthias requested a review from Copilot April 15, 2026 14:50
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds a Linux-only perf-map JVMTI agent that emits perf map entries with source-aware symbols (preferring absolute source paths resolved from the git root), plus Gradle wiring and integration tests to validate the generated perf map output.

Changes:

  • Added native JVMTI agent (libperf_map_agent.so) that listens to JIT code events and writes perf-map entries with path::class::method symbols.
  • Added Java attach helper (PerfMapAgent) and JUnit integration tests that launch a child JVM with the agent to validate output.
  • Updated jmh-core Gradle build to compile/package the agent and updated CI to run the Gradle-based tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
jmh-fork/jmh-core/src/test/java/io/codspeed/perf_map_agent/PerfMapAgentTest.java Adds Linux-only integration tests that validate map file creation and basic line format/content.
jmh-fork/jmh-core/src/main/java/io/codspeed/perf_map_agent/c/perf_map_agent.c Implements the JVMTI agent, source-path resolution via git root discovery + recursive search, and a thread-safe cache.
jmh-fork/jmh-core/src/main/java/io/codspeed/perf_map_agent/PerfMapAgent.java Adds a small Java CLI/API for attaching the agent to a running JVM by PID.
jmh-fork/jmh-core/build.gradle.kts Compiles the perf-map agent on Linux and includes it in resources.
.github/workflows/ci.yml Switches CI test execution to Gradle and enables Gradle caching.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread jmh-fork/jmh-core/native-perf-map-agent/src/main/c/perf_map_agent.c
Comment thread jmh-fork/jmh-core/src/main/java/io/codspeed/perf_map_agent/c/perf_map_agent.c Outdated
Comment thread jmh-fork/jmh-core/src/main/java/io/codspeed/perf_map_agent/c/perf_map_agent.c Outdated
Comment thread jmh-fork/jmh-core/native-perf-map-agent/src/main/c/perf_map_agent.c
Comment thread jmh-fork/jmh-core/src/test/java/io/codspeed/perf_map_agent/PerfMapAgentTest.java Outdated
…resolution

Add a JVMTI agent that hooks CompiledMethodLoad events and writes
/tmp/perf-<pid>.map with source file paths resolved from the git root.

Key features:
- Resolves project source files to absolute paths via git root discovery
- Falls back to clean relative paths for JDK/dependency classes
- Thread-safe source file cache with pthread_once for git root init
- VMDeath callback flushes deferred CompiledMethodLoad events
- Handles lambda/hidden class signatures ($$Lambda/0x...) correctly
- Java attach wrapper (PerfMapAgent) for runtime agent loading

Includes integration tests validating perf map format, source path
resolution, and default map path behavior.
The Maven job couldn't run the perf-map agent integration tests because
it doesn't build the native lib. Switch to Gradle which compiles the
native agent and runs all CodSpeed tests in a single job.
…CodSpeed

When running under CodSpeed (isInstrumented()), load the perf-map
JVMTI agent into benchmark JVMs:

- Forked JVMs (@fork 1+): inject -agentpath: into the fork command
- Current VM (@fork 0): self-attach via the Attach API, relying on
  -Djdk.attach.allowAttachSelf=true set by the CodSpeed runner

The native library is extracted from classpath resources once and
cached. Silently skipped when not available (non-Linux, not built).
@not-matthias not-matthias force-pushed the cod-2516-investigate-node-origin-for-java branch from 802ab83 to eecaad1 Compare April 16, 2026 11:13
Copy link
Copy Markdown

@GuillaumeLagrange GuillaumeLagrange left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

olgtm

Comment thread jmh-fork/jmh-core/build.gradle.kts Outdated
Comment thread .github/workflows/ci.yml
Replace the hand-rolled gcc Exec tasks with Gradle's cpp-library plugin
via two new nested subprojects (jmh-core:native-instrument-hooks and
jmh-core:native-perf-map-agent). Each subproject owns its .c sources
and — for instrument-hooks — the upstream submodule; jmh-core consumes
their linkRelease outputs as resources bundled into jmh-core.jar.

Notes:
- Gradle 9.0 removed the c-library plugin; cpp-library is used with
  -x c to keep .c files compiling as C under g++.
- cpp-library's source set filters for *.cpp/*.cc/*.c++, so .c files
  are added directly to the CppCompile task to bypass that filter.
- The native subprojects are excluded from the shared maven-publish
  block; only jmh-core ships, with both .so files at its jar root.
@not-matthias not-matthias force-pushed the cod-2516-investigate-node-origin-for-java branch from b84d250 to c7c19aa Compare April 16, 2026 18:01
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.

3 participants