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

@ -25,16 +25,16 @@
package java.lang.reflect;
import java.lang.annotation.*;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import jdk.internal.access.SharedSecrets;
import jdk.internal.vm.annotation.Stable;
import sun.reflect.annotation.AnnotationParser;
import sun.reflect.annotation.AnnotationSupport;
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
// with it. Since parameters are immutable, we can
// shallow-copy.
return privateGetParameters().clone();
return parameterData().parameters.clone();
}
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() {
// If this somehow gets called before parameters gets
// initialized, force it into existence.
if (parameters == null) {
privateGetParameters();
}
return hasRealParameterData;
return parameterData().isReal;
}
private transient volatile boolean hasRealParameterData;
private transient volatile Parameter[] parameters;
private ParameterData parameterData() {
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();
native byte[] getTypeAnnotationBytes0();