8146820: JVMCI options should not use System.getProperty directly
Reviewed-by: kvn, dnsimon
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java Fri Jan 15 21:56:43 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java Fri Jan 15 13:08:40 2016 -1000
@@ -27,6 +27,7 @@
import java.lang.reflect.Array;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
@@ -42,11 +43,6 @@
*/
public class HotSpotConstantReflectionProvider implements ConstantReflectionProvider, HotSpotProxified {
- /**
- * Determines whether to treat {@code final} fields with default values as constant.
- */
- private static final boolean TrustFinalDefaultFields = HotSpotJVMCIRuntime.getBooleanProperty("TrustFinalDefaultFields", true);
-
protected final HotSpotJVMCIRuntimeProvider runtime;
protected final HotSpotMethodHandleAccessProvider methodHandleAccess;
protected final HotSpotMemoryAccessProviderImpl memoryAccess;
@@ -249,14 +245,14 @@
* Determines if a value read from a {@code final} instance field is considered constant. The
* implementation in {@link HotSpotConstantReflectionProvider} returns true if {@code value} is
* not the {@link JavaConstant#isDefaultForKind default value} for its kind or if
- * {@link #TrustFinalDefaultFields} is true.
+ * {@link Option#TrustFinalDefaultFields} is true.
*
* @param value a value read from a {@code final} instance field
* @param receiverClass the {@link Object#getClass() class} of object from which the
* {@code value} was read
*/
protected boolean isFinalInstanceFieldValueConstant(JavaConstant value, Class<?> receiverClass) {
- return !value.isDefaultForKind() || TrustFinalDefaultFields;
+ return !value.isDefaultForKind() || Option.TrustFinalDefaultFields.getBoolean();
}
/**
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Fri Jan 15 21:56:43 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java Fri Jan 15 13:08:40 2016 -1000
@@ -26,6 +26,7 @@
import java.io.IOException;
import java.io.OutputStream;
+import java.io.PrintStream;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -85,19 +86,95 @@
}
/**
- * Gets a boolean value based on a system property {@linkplain VM#getSavedProperty(String)
- * saved} at system initialization time. The property name is prefixed with "{@code jvmci.}".
- *
- * @param name the name of the system property to derive a boolean value from using
- * {@link Boolean#parseBoolean(String)}
- * @param def the value to return if there is no system property corresponding to {@code name}
+ * A list of all supported JVMCI options.
*/
- public static boolean getBooleanProperty(String name, boolean def) {
- String value = VM.getSavedProperty("jvmci." + name);
- if (value == null) {
- return def;
+ public enum Option {
+ ImplicitStableValues(boolean.class, true, "Mark well-known stable fields as such."),
+ // Note: The following one is not used (see InitTimer.ENABLED).
+ InitTimer(boolean.class, false, "Specifies if initialization timing is enabled."),
+ PrintConfig(boolean.class, false, "Prints all HotSpotVMConfig fields."),
+ PrintFlags(boolean.class, false, "Prints all JVMCI flags and exits."),
+ ShowFlags(boolean.class, false, "Prints all JVMCI flags and continues."),
+ TraceMethodDataFilter(String.class, null, ""),
+ TrustFinalDefaultFields(boolean.class, true, "Determines whether to treat final fields with default values as constant.");
+
+ /**
+ * The prefix for system properties that are JVMCI options.
+ */
+ private static final String JVMCI_OPTION_PROPERTY_PREFIX = "jvmci.";
+
+ /**
+ * Marker for uninitialized flags.
+ */
+ private static final String UNINITIALIZED = "UNINITIALIZED";
+
+ private final Class<?> type;
+ private Object value;
+ private final Object defaultValue;
+ private boolean isDefault;
+ private final String help;
+
+ private Option(Class<?> type, Object defaultValue, String help) {
+ assert Character.isUpperCase(name().charAt(0)) : "Option name must start with upper-case letter: " + name();
+ this.type = type;
+ this.value = UNINITIALIZED;
+ this.defaultValue = defaultValue;
+ this.help = help;
}
- return Boolean.parseBoolean(value);
+
+ private Object getValue() {
+ if (value == UNINITIALIZED) {
+ String propertyValue = VM.getSavedProperty(JVMCI_OPTION_PROPERTY_PREFIX + name());
+ if (propertyValue == null) {
+ this.value = defaultValue;
+ this.isDefault = true;
+ } else {
+ if (type == boolean.class) {
+ this.value = Boolean.parseBoolean(propertyValue);
+ } else if (type == String.class) {
+ this.value = propertyValue;
+ } else {
+ throw new JVMCIError("Unexpected option type " + type);
+ }
+ this.isDefault = false;
+ }
+ // Saved properties should not be interned - let's be sure
+ assert value != UNINITIALIZED;
+ }
+ return value;
+ }
+
+ /**
+ * Returns the option's value as boolean.
+ *
+ * @return option's value
+ */
+ public boolean getBoolean() {
+ return (boolean) getValue();
+ }
+
+ /**
+ * Returns the option's value as String.
+ *
+ * @return option's value
+ */
+ public String getString() {
+ return (String) getValue();
+ }
+
+ /**
+ * Prints all option flags to {@code out}.
+ *
+ * @param out stream to print to
+ */
+ public static void printFlags(PrintStream out) {
+ out.println("[List of JVMCI options]");
+ for (Option option : values()) {
+ Object value = option.getValue();
+ String assign = option.isDefault ? ":=" : " =";
+ out.printf("%9s %-40s %s %-14s %s%n", option.type.getSimpleName(), option, assign, value, option.help);
+ }
+ }
}
public static HotSpotJVMCIBackendFactory findFactory(String architecture) {
@@ -164,7 +241,16 @@
}
metaAccessContext = context;
- if (Boolean.valueOf(System.getProperty("jvmci.printconfig"))) {
+ boolean printFlags = Option.PrintFlags.getBoolean();
+ boolean showFlags = Option.ShowFlags.getBoolean();
+ if (printFlags || showFlags) {
+ Option.printFlags(System.out);
+ if (printFlags) {
+ System.exit(0);
+ }
+ }
+
+ if (Option.PrintConfig.getBoolean()) {
printConfig(config, compilerToVm);
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java Fri Jan 15 21:56:43 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java Fri Jan 15 13:08:40 2016 -1000
@@ -29,6 +29,7 @@
import java.lang.reflect.Field;
import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.JavaType;
import jdk.vm.ci.meta.LocationIdentity;
import jdk.vm.ci.meta.MetaAccessProvider;
@@ -41,11 +42,6 @@
*/
class HotSpotResolvedJavaFieldImpl implements HotSpotResolvedJavaField, HotSpotProxified {
- /**
- * Mark well-known stable fields as such.
- */
- private static final boolean ImplicitStableValues = HotSpotJVMCIRuntime.getBooleanProperty("ImplicitStableValues", true);
-
private final HotSpotResolvedObjectTypeImpl holder;
private final String name;
private JavaType type;
@@ -198,7 +194,7 @@
return true;
}
assert getAnnotation(Stable.class) == null;
- if (ImplicitStableValues && isImplicitStableField()) {
+ if (Option.ImplicitStableValues.getBoolean() && isImplicitStableField()) {
return true;
}
return false;
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Fri Jan 15 21:56:43 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java Fri Jan 15 13:08:40 2016 -1000
@@ -37,6 +37,7 @@
import java.util.Map;
import jdk.vm.ci.common.JVMCIError;
+import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.ConstantPool;
import jdk.vm.ci.meta.DefaultProfilingInfo;
@@ -417,8 +418,6 @@
return false;
}
- private static final String TraceMethodDataFilter = System.getProperty("jvmci.traceMethodDataFilter");
-
@Override
public ProfilingInfo getProfilingInfo(boolean includeNormal, boolean includeOSR) {
ProfilingInfo info;
@@ -427,7 +426,8 @@
long metaspaceMethodData = UNSAFE.getAddress(metaspaceMethod + config().methodDataOffset);
if (metaspaceMethodData != 0) {
methodData = new HotSpotMethodData(metaspaceMethodData, this);
- if (TraceMethodDataFilter != null && this.format("%H.%n").contains(TraceMethodDataFilter)) {
+ String methodDataFilter = Option.TraceMethodDataFilter.getString();
+ if (methodDataFilter != null && this.format("%H.%n").contains(methodDataFilter)) {
System.out.println("Raw method data for " + this.format("%H.%n(%p)") + ":");
System.out.println(methodData.toString());
}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/InitTimer.java Fri Jan 15 21:56:43 2016 +0300
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/InitTimer.java Fri Jan 15 13:08:40 2016 -1000
@@ -65,9 +65,10 @@
}
/**
- * Specifies if initialization timing is enabled.
+ * Specifies if initialization timing is enabled. Note: This property cannot use
+ * {@code HotSpotJVMCIRuntime.Option} since that class is not visible from this package.
*/
- private static final boolean ENABLED = Boolean.getBoolean("jvmci.inittimer") || Boolean.getBoolean("jvmci.runtime.TimeInit");
+ private static final boolean ENABLED = Boolean.getBoolean("jvmci.InitTimer");
public static final AtomicInteger nesting = ENABLED ? new AtomicInteger() : null;
public static final String SPACES = " ";