changeset 23721:c61554b3f6df

compiler selection should work without -Djvmci.Compiler (JDK-8160730)
author Doug Simon <doug.simon@oracle.com>
date Sat, 02 Jul 2016 01:00:12 +0200
parents 286b19732922
children eb3fb34bcd47
files jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java jvmci/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java
diffstat 3 files changed, 94 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Sat Jul 02 00:48:02 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Sat Jul 02 01:00:12 2016 +0200
@@ -22,6 +22,10 @@
  */
 package jdk.vm.ci.hotspot;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+
 import jdk.vm.ci.code.CompilationRequest;
 import jdk.vm.ci.code.CompilationRequestResult;
 import jdk.vm.ci.common.JVMCIError;
@@ -29,6 +33,7 @@
 import jdk.vm.ci.runtime.JVMCICompiler;
 import jdk.vm.ci.runtime.JVMCIRuntime;
 import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+import jdk.vm.ci.runtime.services.JVMCICompilerFactory.AutoSelectionPrecedence;
 import jdk.vm.ci.services.Services;
 
 final class HotSpotJVMCICompilerConfig {
@@ -56,6 +61,54 @@
     private static JVMCICompilerFactory compilerFactory;
 
     /**
+     * Comparator that sorts available {@link JVMCICompilerFactory} objects according to their
+     * {@link JVMCICompilerFactory#getAutoSelectionRelationTo(JVMCICompilerFactory) relative}
+     * auto-selection preferences. Factories with higher preferences are sorted earlier. If a
+     */
+    static class FactoryComparator implements Comparator<JVMCICompilerFactory> {
+
+        /**
+         * Compares two compiler factories and returns -1 if {@code o1} should be auto-selected over
+         * {@code o2}, -1 if {@code o1} should be auto-selected over {@code o2} or 0 if
+         * {@code o1 == o2 || o1.getClass() == o2.getClass()}.
+         *
+         * @throws JVMCIError there is no auto-selection preference relation between {@code o1} and
+         *             {@code o2}
+         */
+        public int compare(JVMCICompilerFactory o1, JVMCICompilerFactory o2) {
+            if (o1 == o2 || o1.getClass() == o2.getClass()) {
+                return 0;
+            }
+            AutoSelectionPrecedence o1Precedence = o1.getAutoSelectionRelationTo(o2);
+            AutoSelectionPrecedence o2Precedence = o2.getAutoSelectionRelationTo(o1);
+            switch (o1Precedence) {
+                case HIGHER: {
+                    assert o2Precedence != o1Precedence : "auto selection precedence of " + o1 + " and " + o2 + " cannot both be " + o1Precedence;
+                    return -1;
+                }
+                case LOWER: {
+                    assert o2Precedence != o1Precedence : "auto selection precedence of " + o1 + " and " + o2 + " cannot both be " + o1Precedence;
+                    return 1;
+                }
+                case UNRELATED: {
+                    switch (o2Precedence) {
+                        case HIGHER: {
+                            return 1;
+                        }
+                        case LOWER: {
+                            return -1;
+                        }
+                        default:
+                            break;
+                    }
+                }
+            }
+            // No auto-selection preference relation between o1 and o2
+            throw new JVMCIError("JVMCI compiler must be specified with the '%s' system property", Option.JVMCI_OPTION_PROPERTY_PREFIX + Option.Compiler);
+        }
+    }
+
+    /**
      * Gets the selected system compiler factory.
      *
      * @return the selected system compiler factory
@@ -67,7 +120,6 @@
             if (compilerName != null) {
                 for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
                     if (f.getCompilerName().equals(compilerName)) {
-                        f.onSelection();
                         factory = f;
                     }
                 }
@@ -75,8 +127,24 @@
                     throw new JVMCIError("JVMCI compiler '%s' not found", compilerName);
                 }
             } else {
-                factory = new DummyCompilerFactory();
+                // Auto selection
+                ArrayList<JVMCICompilerFactory> factories = new ArrayList<>();
+                for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
+                    factories.add(f);
+                }
+                if (!factories.isEmpty()) {
+                    if (factories.size() == 1) {
+                        factory = factories.get(0);
+                    } else {
+                        Collections.sort(factories, new FactoryComparator());
+                        factory = factories.get(0);
+                    }
+                } else {
+                    factory = new DummyCompilerFactory();
+                }
+                factory.onSelection();
             }
+            assert factory != null;
             compilerFactory = factory;
         }
         return compilerFactory;
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Sat Jul 02 00:48:02 2016 +0200
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Sat Jul 02 01:00:12 2016 +0200
@@ -99,7 +99,7 @@
         /**
          * The prefix for system properties that are JVMCI options.
          */
-        private static final String JVMCI_OPTION_PROPERTY_PREFIX = "jvmci.";
+        static final String JVMCI_OPTION_PROPERTY_PREFIX = "jvmci.";
 
         /**
          * Marker for uninitialized flags.
--- a/jvmci/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java	Sat Jul 02 00:48:02 2016 +0200
+++ b/jvmci/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java	Sat Jul 02 01:00:12 2016 +0200
@@ -54,6 +54,29 @@
     }
 
     /**
+     * Constants denoting the relative precedence between two factories in terms of
+     * {@linkplain JVMCICompilerFactory#getAutoSelectionRelationTo(JVMCICompilerFactory) auto
+     * selecting} which factory to use.
+     */
+    public enum AutoSelectionPrecedence {
+        UNRELATED,
+        HIGHER,
+        LOWER;
+    }
+
+    /**
+     * Gets the precedence of factory relative to another factory in terms of selecting which
+     * factory to use in absence of information (such as a system property) specifying a specific
+     * factory.
+     *
+     * @param other a factory guaranteed to have a different concrete type than this factory
+     * @return the precedence of selecting this factory over {@code other}
+     */
+    public AutoSelectionPrecedence getAutoSelectionRelationTo(JVMCICompilerFactory other) {
+        return AutoSelectionPrecedence.UNRELATED;
+    }
+
+    /**
      * Get the name of this compiler. The name is used by JVMCI to determine which factory to use.
      */
     public abstract String getCompilerName();