Hi all,

The Java FF&M API includes functionality to both initialize and read from 
thread-local data prior to and immediately after downcalls, respectively, 
through the `Linker.Option::captureCallState` API. This is useful, as an 
example, when setting or capturing `errno` when interfacing with C functions. 
However, using this linker option introduces some invocation overhead at 
runtime.

This RFE introduces a JMH microbenchmark which quantifies this overhead. A 
simple downcall to `strtol` is measured with and without call state capturing. 

Testing: GHA for sanity testing.

# Benchmarking Results

I have executed this benchmark on Oracle-supported platforms, the results can 
be found below. For each platform, I've done two trials corresponding to 
different JDKs: one being the current HEAD ("current", based on 
8357de88aa35ee998fefe321ee6dae9eb4993fa6), and one with 
[JDK-8378559](https://bugs.openjdk.org/browse/JDK-8378559) reverted ("legacy", 
revert commit on top of 8357de88aa35ee998fefe321ee6dae9eb4993fa6). This one-off 
experiment is insightful since 
[JDK-8378559](https://bugs.openjdk.org/browse/JDK-8378559) increased the 
overhead of downcalls using state capturing by introducing thread-local data 
initialization. The performance impact of this change was previously 
unquantified.

## Linux x64

**Current:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  38.442 ± 
0.016  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  45.425 ± 
1.826  ns/op


**Legacy:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  39.224 ± 
0.789  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  41.011 ± 
0.058  ns/op


## Linux AArch64

**Current:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  45.396 ± 
0.185  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  56.116 ± 
0.463  ns/op


**Legacy:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  44.859 ± 
0.183  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  51.721 ± 
0.153  ns/op


## macOS x64

**Current:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  41.388 ± 
0.547  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  46.102 ± 
0.208  ns/op


**Legacy:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  40.929 ± 
0.138  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  43.938 ± 
0.385  ns/op


## macOS AArch64

**Current:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  16.892 ± 
0.008  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  21.933 ± 
0.016  ns/op


**Legacy:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  16.894 ± 
0.008  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  19.083 ± 
0.009  ns/op


## Windows x64

**Current:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  39.711 ± 
0.031  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  63.534 ± 
0.208  ns/op


**Legacy:**

Benchmark                                               Mode  Cnt   Score   
Error  Units
CaptureCallStateOverheadBench.doNotUseCaptureCallState  avgt   30  40.532 ± 
0.544  ns/op
CaptureCallStateOverheadBench.useCaptureCallState       avgt   30  50.759 ± 
0.275  ns/op


---------
- [x] I confirm that I make this contribution in accordance with the [OpenJDK 
Interim AI Policy](https://openjdk.org/legal/ai).

-------------

Commit messages:
 - Different long sizes on different platforms.
 - Use C standard library for the benchmark instead.
 - Benchmark to measure call state capturing overhead.

Changes: https://git.openjdk.org/jdk/pull/30719/files
  Webrev: https://webrevs.openjdk.org/?repo=jdk&pr=30719&range=00
  Issue: https://bugs.openjdk.org/browse/JDK-8379630
  Stats: 126 lines in 1 file changed: 126 ins; 0 del; 0 mod
  Patch: https://git.openjdk.org/jdk/pull/30719.diff
  Fetch: git fetch https://git.openjdk.org/jdk.git pull/30719/head:pull/30719

PR: https://git.openjdk.org/jdk/pull/30719

Reply via email to