[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-compiler-dev mailing list