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,13 +421,19 @@ 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) { boolean hasRealParameterData() {
return parameterData().isReal;
}
// Otherwise, go to the JVM to get them private ParameterData parameterData() {
ParameterData parameterData = this.parameterData;
if (parameterData != null) {
return parameterData;
}
Parameter[] tmp;
// Go to the JVM to get them
try { try {
tmp = getParameters0(); tmp = getParameters0();
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -437,30 +443,18 @@ public abstract sealed class Executable extends AccessibleObject
// If we get back nothing, then synthesize parameters // If we get back nothing, then synthesize parameters
if (tmp == null) { if (tmp == null) {
hasRealParameterData = false;
tmp = synthesizeAllParams(); tmp = synthesizeAllParams();
parameterData = new ParameterData(tmp, false);
} else { } else {
hasRealParameterData = true;
verifyParameters(tmp); verifyParameters(tmp);
parameterData = new ParameterData(tmp, true);
}
return this.parameterData = parameterData;
} }
parameters = tmp; private transient @Stable ParameterData parameterData;
}
return tmp; record ParameterData(@Stable Parameter[] parameters, boolean isReal) {}
}
boolean hasRealParameterData() {
// If this somehow gets called before parameters gets
// initialized, force it into existence.
if (parameters == null) {
privateGetParameters();
}
return hasRealParameterData;
}
private transient volatile boolean hasRealParameterData;
private transient volatile Parameter[] parameters;
private native Parameter[] getParameters0(); private native Parameter[] getParameters0();
native byte[] getTypeAnnotationBytes0(); native byte[] getTypeAnnotationBytes0();