8146820: JVMCI options should not use System.getProperty directly
authortwisti
Fri, 15 Jan 2016 13:08:40 -1000
changeset 35570 584ae5cfe100
parent 35569 a2cdb4062a5d
child 35571 63e185035789
child 35572 c864053d0405
8146820: JVMCI options should not use System.getProperty directly Reviewed-by: kvn, dnsimon
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotConstantReflectionProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaFieldImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotResolvedJavaMethodImpl.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.inittimer/src/jdk/vm/ci/inittimer/InitTimer.java
--- 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 = "                                            ";