8288327: Executable.hasRealParameterData should not be volatile

Reviewed-by: plevart
This commit is contained in:
Sergey Tsypanov 2022-08-04 15:15:49 +00:00 committed by Peter Levart
parent d4a795d75a
commit aa557b9b01

View File

@ -25,16 +25,16 @@
package java.lang.reflect; package java.lang.reflect;
import java.lang.annotation.*; import java.lang.annotation.Annotation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Objects; import java.util.Objects;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.stream.Stream;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import jdk.internal.vm.annotation.Stable;
import sun.reflect.annotation.AnnotationParser; import sun.reflect.annotation.AnnotationParser;
import sun.reflect.annotation.AnnotationSupport; import sun.reflect.annotation.AnnotationSupport;
import sun.reflect.annotation.TypeAnnotationParser; import sun.reflect.annotation.TypeAnnotationParser;
@ -382,7 +382,7 @@ public abstract sealed class Executable extends AccessibleObject
// Need to copy the cached array to prevent users from messing // Need to copy the cached array to prevent users from messing
// with it. Since parameters are immutable, we can // with it. Since parameters are immutable, we can
// shallow-copy. // shallow-copy.
return privateGetParameters().clone(); return parameterData().parameters.clone();
} }
private Parameter[] synthesizeAllParams() { private Parameter[] synthesizeAllParams() {
@ -421,46 +421,40 @@ public abstract sealed class Executable extends AccessibleObject
} }
} }
private Parameter[] privateGetParameters() {
// Use tmp to avoid multiple writes to a volatile.
Parameter[] tmp = parameters;
if (tmp == null) {
// Otherwise, go to the JVM to get them
try {
tmp = getParameters0();
} catch(IllegalArgumentException e) {
// Rethrow ClassFormatErrors
throw new MalformedParametersException("Invalid constant pool index");
}
// If we get back nothing, then synthesize parameters
if (tmp == null) {
hasRealParameterData = false;
tmp = synthesizeAllParams();
} else {
hasRealParameterData = true;
verifyParameters(tmp);
}
parameters = tmp;
}
return tmp;
}
boolean hasRealParameterData() { boolean hasRealParameterData() {
// If this somehow gets called before parameters gets return parameterData().isReal;
// initialized, force it into existence.
if (parameters == null) {
privateGetParameters();
}
return hasRealParameterData;
} }
private transient volatile boolean hasRealParameterData; private ParameterData parameterData() {
private transient volatile Parameter[] parameters; ParameterData parameterData = this.parameterData;
if (parameterData != null) {
return parameterData;
}
Parameter[] tmp;
// Go to the JVM to get them
try {
tmp = getParameters0();
} catch (IllegalArgumentException e) {
// Rethrow ClassFormatErrors
throw new MalformedParametersException("Invalid constant pool index");
}
// If we get back nothing, then synthesize parameters
if (tmp == null) {
tmp = synthesizeAllParams();
parameterData = new ParameterData(tmp, false);
} else {
verifyParameters(tmp);
parameterData = new ParameterData(tmp, true);
}
return this.parameterData = parameterData;
}
private transient @Stable ParameterData parameterData;
record ParameterData(@Stable Parameter[] parameters, boolean isReal) {}
private native Parameter[] getParameters0(); private native Parameter[] getParameters0();
native byte[] getTypeAnnotationBytes0(); native byte[] getTypeAnnotationBytes0();