ShenandoahOptimizeFinals is an illegal optimization
Roland Westrelin
rwestrel at redhat.com
Wed Oct 18 12:25:00 UTC 2017
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.
More information about the shenandoah-dev
mailing list