[13] RFR (M): 8223213: Implement fast class initialization checks on x86-64
Claes Redestad
claes.redestad at oracle.com
Thu May 2 11:03:18 UTC 2019
Hi Vladimir,
On 2019-05-02 01:17, Vladimir Ivanov wrote:
> Performance experiments with clojure [2] demonstrated that the fix
> almost completely recuperates the regression:
>
> (1) always reresolve (w/o the fix): ~12,0s ( 1x)
> (2) C1/C2 barriers only: ~3,8s (~3x)
> (3) int/C1/C2 barriers: ~3,2s (-20%)
> --------
> (4) barriers disabled for invokestatic ~3,2s
good stuff!
Just to add a few data points I turned some of my earlier experiments to
try and isolate some of these issues into a little stress test:
BadStress[1]:
11.0.1: 136ms
11.0.2: 13500ms
jdk/jdk baseline: 126ms
jdk/jdk patched: 123ms
GoodStress[2] (baseline):
11.0.1: 56ms
11.0.2: 54ms
jdk/jdk baseline: 48ms
jdk/jdk patched: 47ms
Observations:
- On latest jdk/jdk, we've already recuperated most of the cost exposed
in these synthetic tests due related fixes (mainly
https://bugs.openjdk.java.net/browse/JDK-8188133 and
https://bugs.openjdk.java.net/browse/JDK-8219974 ), but the patch
helps a bit here too and we're net faster than 11.0.1 (also when
taking into account how startup in general has improved since)
- The small 1ms startup improvement with the patch on the baseline test
is sustained and significant, indicating we have some internal JDK
classes exercised during bootstrap which benefit directly from your
fixes. I've verified this improvement translates to all our other
small-app startup tests.
- My tests were too naïve to capture all the overheads seen with clj
- Likely still good performance advice to avoid heavy lifting in static
initializers.
All in all I think this is a great improvement and hope the added
complexity is deemed acceptable.
Thanks!
/Claes
[1]
public class BadStress {
static void foo() {}
static void bar() {}
public static class Helper {
static void foo() { BadStress.foo(); }
}
static {
long start = System.nanoTime();
for (int i = 0; i < 10_000_000; i++) {
Helper.foo();
}
for (int i = 0; i < 10_000_000; i++) {
bar();
}
long end = System.nanoTime();
System.out.println("Elapsed: " + (end - start) + " ns");
}
public static void main(String... args) {}
}
[2]
public class GoodStress {
public static class Helper {
static void foo() {}
static void bar() {}
}
static {
long start = System.nanoTime();
for (int i = 0; i < 10_000_000; i++) {
Helper.foo();
}
for (int i = 0; i < 10_000_000; i++) {
Helper.bar();
}
long end = System.nanoTime();
System.out.println("Elapsed: " + (end - start) + " ns");
}
public static void main(String... args) {}
}
More information about the hotspot-runtime-dev
mailing list