ShenandoahOptimizeFinals is an illegal optimization

Roman Kennke rkennke at redhat.com
Wed Oct 18 12:51:09 UTC 2017


Am 18.10.2017 um 14:25 schrieb Roland Westrelin:
> This is a follow up to:
>
> http://mail.openjdk.java.net/pipermail/shenandoah-dev/2017-October/003960.html
>
> If we have something like:
>
> public class TestFinal {
>      final int field;
>      static TestFinal tf;
>      TestFinal() {
>          tf = this;
>          field = 0x42;
>      }
>
>      public static void main(String[] args) {
>          new TestFinal();
>          // read tf.field
>      }
> }
>
> the object can be evacuated while it is being constructed between the 2
> assignments. In that case tf points to from space with a value of zero
> for field "field". If tf.field is used later own, because field is
> final, with +ShenandoahOptimizeFinals, there will be no read barrier (in
> compiled code), so it will read 0 instead of 42.
>
> I observe something similar in practice with
> sun.security.jca.ProviderList:
>
>      private final List<Provider> userList = new AbstractList<Provider>() {
>          public int size() {
>              return configs.length;
>          }
>          public Provider get(int index) {
>              return getProvider(index);
>          }
>      };
>
> initializes an instance of an inner class which contains a reference to
> ProviderList in a final field. That happens before the instance itself
> is initialized so fields of ProviderList may be set after the object is
> evacuated but userList may have a reference to the object before it is
> evacuated. The following code in java.security.SecureRandom:
>
>      private static String getPrngAlgorithm() {
>          for (Provider p : Providers.getProviderList().providers()) {
>              for (Service s : p.getServices()) {
>                  if (s.getType().equals("SecureRandom")) {
>                      return s.getAlgorithm();
>                  }
>              }
>          }
>          return null;
>      }
>
> goes through method size() above which reads configs in ProviderList
> through the final field and may get a null value for configs eventhough
> it was initialized in the evacuated copy.
>
> I'm working on a patch that disables ShenandoahOptimizeFinals for
> instance fields.
>
> Roland.

Ok. That optimization hasn't gained much anyway iirc.

I wonder: if it's broken for instance fields, is it broken for static 
fields too, for the same reasons? Replace the constructor with the 
<clinit> in your example above and get the same problem, if the Class 
instance is evacuated during clinit ? Or is that not possible?

Roman



More information about the shenandoah-dev mailing list