Skip to content

chore: add FFM coverage map benchmarks - #1070

Open
kyakdan wants to merge 1 commit into
mainfrom
ffm-coverage-map-benchmark
Open

kyakdan wants to merge 1 commit into
mainfrom
ffm-coverage-map-benchmark

Conversation

@kyakdan

@kyakdan kyakdan commented Oct 14, 2026

Copy link
Copy Markdown
Member

Refs #1069

sun.misc.Unsafe memory access is deprecated for removal (JEP 471/498) and warns on JDK 24+. CoverageMap.recordCoverage runs on every instrumented edge, so this PR adds FFM-backed coverage maps to CoverageInstrumentationBenchmark to measure what replacing Unsafe would cost:

  • FfmCoverageMap uses MemorySegment directly (Java 22 source).
  • FfmMethodHandleCoverageMap uses the same API via method handles. It compiles with Java 8 source level, so it could ship in the same jar as the Unsafe-backed map and only be loaded on JDK 22+.

Both use the same update rule, instrumentation strategy and map size as the existing Unsafe benchmarks. Since FFM requires JDK 22+, the FFM benchmarks are only built with --java_runtime_version=remotejdk_25, the only JDK >= 22 that rules_java provides. CI runs on JDK 8 and 21, so it doesn't run them.

Results

JDK 25.0.2, macOS arm64, JMH defaults (5 forks, 5 × 10 s warmup and measurement):

Benchmark ops/s vs. Unsafe_NeverZero2
uninstrumented 9.03M ± 0.58M
staticMethod_Unsafe_NeverZero2 (what Jazzer uses today) 3.73M ± 0.04M baseline
staticMethod_Ffm_NeverZero 2.93M ± 0.01M −21.5%
staticMethod_FfmMethodHandle_NeverZero 2.87M ± 0.04M −23.2%
staticMethod_DirectByteBuffer2_NeverZero 2.46M ± 0.63M −34%

FFM costs about 21% throughput on this benchmark, which only measures the instrumented target, not libFuzzer's loop. The method-handle variant is within about 2% of direct FFM, so a single release could use Unsafe where it's still allowed and fall back to FFM otherwise.

Running

bazel run --java_runtime_version=remotejdk_25 \
  //src/jmh/java/com/code_intelligence/jazzer/instrumentor:CoverageInstrumentationBenchmark

sun.misc.Unsafe memory access is deprecated for removal (JEP 471/498)
and warns on JDK 24+. Add coverage maps backed by the Foreign Function
& Memory API to CoverageInstrumentationBenchmark to compare them with
the Unsafe-backed map Jazzer uses today:

- FfmCoverageMap uses MemorySegment directly (Java 22 source).
- FfmMethodHandleCoverageMap accesses the same API via method handles,
  so it compiles with Java 8 source level and could ship in the same
  jar as the Unsafe-backed map.

Since FFM requires JDK 22+, the FFM benchmarks are only built with
--java_runtime_version=remotejdk_25.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fc8e7077-31cc-47a3-acb9-050440f42ea5

This branch has not been deployed

No deployments
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