changeset 21623:d2113f5ae550

Merge.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 31 May 2015 23:58:09 +0200
parents 45dea3e24169 (current diff) 838f005f9aec (diff)
children dcf65e8b9fd9
files graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeFactory.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java
diffstat 21 files changed, 385 insertions(+), 219 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java	Sun May 31 23:57:57 2015 +0200
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/Graal.java	Sun May 31 23:58:09 2015 +0200
@@ -36,12 +36,9 @@
     private static final GraalRuntime runtime = initializeRuntime();
 
     private static GraalRuntime initializeRuntime() {
-        GraalRuntime rt = null;
-        for (GraalRuntimeFactory factory : Services.load(GraalRuntimeFactory.class)) {
-            assert rt == null : String.format("Multiple %s implementations found: %s, %s", GraalRuntime.class.getName(), rt.getClass().getName(), factory.getRuntime().getClass().getName());
-            rt = factory.getRuntime();
-        }
-        if (rt != null) {
+        GraalRuntimeAccess access = Services.loadSingle(GraalRuntimeAccess.class, false);
+        if (access != null) {
+            GraalRuntime rt = access.getRuntime();
             // The constant is patched in-situ by the build system
             System.setProperty("graal.version", "@@graal.version@@".trim());
             assert !System.getProperty("graal.version").startsWith("@@") && !System.getProperty("graal.version").endsWith("@@") : "Graal version string constant was not patched by build system";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeAccess.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.api.runtime;
+
+import com.oracle.jvmci.service.*;
+
+/**
+ * A {@linkplain Service JVMCI service} that provides access to a {@link GraalRuntime}
+ * implementation.
+ */
+public interface GraalRuntimeAccess extends Service {
+
+    /**
+     * Gets the {@link GraalRuntime} implementation available via this access object.
+     */
+    GraalRuntime getRuntime();
+}
--- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeFactory.java	Sun May 31 23:57:57 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.api.runtime;
-
-import com.oracle.jvmci.service.*;
-
-public interface GraalRuntimeFactory extends Service {
-
-    GraalRuntime getRuntime();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeAccess.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.hotspot;
+
+import com.oracle.graal.api.runtime.*;
+import com.oracle.jvmci.service.*;
+
+@ServiceProvider(GraalRuntimeAccess.class)
+public class HotSpotGraalRuntimeAccess implements GraalRuntimeAccess {
+
+    @Override
+    public GraalRuntime getRuntime() {
+        return HotSpotGraalRuntime.runtime();
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntimeFactory.java	Sun May 31 23:57:57 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.hotspot;
-
-import com.oracle.graal.api.runtime.*;
-import com.oracle.jvmci.service.*;
-
-@ServiceProvider(GraalRuntimeFactory.class)
-public class HotSpotGraalRuntimeFactory implements GraalRuntimeFactory {
-
-    @Override
-    public GraalRuntime getRuntime() {
-        return HotSpotGraalRuntime.runtime();
-    }
-}
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Sun May 31 23:57:57 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java	Sun May 31 23:58:09 2015 +0200
@@ -354,9 +354,6 @@
         return null;
     }
 
-    /**
-     * Called from the VM.
-     */
     public static NativeFunctionInterface createNativeFunctionInterface() {
         HotSpotVMConfig config = HotSpotGraalRuntime.runtime().getConfig();
         Backend backend = HotSpotGraalRuntime.runtime().getHostBackend();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle.hotspot;
+
+import com.oracle.jvmci.service.*;
+import com.oracle.truffle.api.*;
+
+@ServiceProvider(TruffleRuntimeAccess.class)
+public class HotSpotTruffleRuntimeAccess implements TruffleRuntimeAccess {
+    public TruffleRuntime getRuntime() {
+        return HotSpotTruffleRuntime.makeInstance();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.truffle.hotspot.nfi;
+
+import com.oracle.graal.truffle.hotspot.*;
+import com.oracle.jvmci.service.*;
+import com.oracle.nfi.api.*;
+
+@ServiceProvider(NativeFunctionInterfaceAccess.class)
+public class HotSpotNativeFunctionInterfaceAccess implements NativeFunctionInterfaceAccess {
+    private final NativeFunctionInterface instance = HotSpotTruffleRuntime.createNativeFunctionInterface();
+
+    public NativeFunctionInterface getNativeFunctionInterface() {
+        return instance;
+    }
+}
--- a/graal/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java	Sun May 31 23:57:57 2015 +0200
+++ b/graal/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java	Sun May 31 23:58:09 2015 +0200
@@ -29,9 +29,10 @@
 import sun.reflect.*;
 
 /**
- * A mechanism on top of the standard {@link ServiceLoader} that enables a runtime to efficiently
- * load services marked by {@link Service}. This may be important for services loaded early in the
- * runtime initialization process.
+ * A mechanism on top of the standard {@link ServiceLoader} that enables JVMCI enabled runtime to
+ * efficiently load services marked by {@link Service}. This is important to avoid the performance
+ * overhead of the standard service loader mechanism for services loaded in the runtime
+ * initialization process.
  */
 public class Services {
 
@@ -54,6 +55,7 @@
     @SuppressWarnings("unchecked")
     @CallerSensitive
     public static <S> Iterable<S> load(Class<S> service) {
+        // TODO(ds): add SecurityManager checks
         if (Service.class.isAssignableFrom(service)) {
             try {
                 return (Iterable<S>) cache.get(service);
@@ -67,5 +69,50 @@
         return ServiceLoader.load(service, cl);
     }
 
+    /**
+     * Gets the implementation for a given service for which at most one implementation must be
+     * available.
+     *
+     * @param service the service whose implementation is being requested
+     * @param required specifies if an {@link InternalError} should be thrown if no implementation
+     *            of {@code service} is available
+     */
+    @SuppressWarnings("unchecked")
+    @CallerSensitive
+    public static <S> S loadSingle(Class<S> service, boolean required) {
+        // TODO(ds): add SecurityManager checks
+        Iterable<S> impls = null;
+        if (Service.class.isAssignableFrom(service)) {
+            try {
+                impls = (Iterable<S>) cache.get(service);
+            } catch (UnsatisfiedLinkError e) {
+                // Fall back to standard ServiceLoader
+            }
+        }
+
+        if (impls == null) {
+            // Need to use the ClassLoader of the caller
+            ClassLoader cl = Reflection.getCallerClass().getClassLoader();
+            impls = ServiceLoader.load(service, cl);
+        }
+        S singleImpl = null;
+        for (S impl : impls) {
+            if (singleImpl != null) {
+                throw new InternalError(String.format("Multiple %s implementations found: %s, %s", service.getName(), singleImpl.getClass().getName(), impl.getClass().getName()));
+            }
+            singleImpl = impl;
+        }
+        if (singleImpl == null && required) {
+            String javaHome = System.getProperty("java.home");
+            String vmName = System.getProperty("java.vm.name");
+            Formatter errorMessage = new Formatter();
+            errorMessage.format("The VM does not expose required service %s.%n", service.getName());
+            errorMessage.format("Currently used Java home directory is %s.%n", javaHome);
+            errorMessage.format("Currently used VM configuration is: %s", vmName);
+            throw new UnsupportedOperationException(errorMessage.toString());
+        }
+        return singleImpl;
+    }
+
     private static native <S> S[] getServiceImpls(Class<?> service);
 }
--- a/graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java	Sun May 31 23:57:57 2015 +0200
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/NativeFunctionInterfaceRuntime.java	Sun May 31 23:58:09 2015 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.nfi;
 
+import com.oracle.jvmci.service.*;
 import com.oracle.nfi.api.*;
 
 /**
@@ -31,14 +32,6 @@
     private static final NativeFunctionInterface INSTANCE;
 
     /**
-     * Creates a new {@link NativeFunctionInterface}.
-     *
-     * @throws UnsatisfiedLinkError if not running on a VM that provides a
-     *             {@link NativeFunctionInterface}
-     */
-    private static native NativeFunctionInterface createInterface();
-
-    /**
      * Gets the {@link NativeFunctionInterface} (if any) provided by the VM.
      *
      * @return null if the VM does not provide a {@link NativeFunctionInterface}
@@ -48,11 +41,11 @@
     }
 
     static {
-        NativeFunctionInterface instance;
-        try {
-            instance = createInterface();
-        } catch (UnsatisfiedLinkError e) {
-            instance = null;
+
+        NativeFunctionInterface instance = null;
+        NativeFunctionInterfaceAccess access = Services.loadSingle(NativeFunctionInterfaceAccess.class, false);
+        if (access != null) {
+            instance = access.getNativeFunctionInterface();
         }
         INSTANCE = instance;
     }
--- a/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java	Sun May 31 23:57:57 2015 +0200
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterface.java	Sun May 31 23:58:09 2015 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.nfi.api;
 
+import com.oracle.jvmci.service.*;
+
 /**
  * Interface to get a {@linkplain NativeFunctionHandle handle} or {@linkplain NativeFunctionPointer
  * pointer} to a native function or a {@linkplain NativeLibraryHandle handle} to an open native
  * library.
  */
-public interface NativeFunctionInterface {
+public interface NativeFunctionInterface extends Service {
 
     /**
      * Resolves and returns a handle to an open native library. This method will open the library
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.nfi/src/com/oracle/nfi/api/NativeFunctionInterfaceAccess.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.nfi.api;
+
+import com.oracle.jvmci.service.*;
+
+/**
+ * A {@linkplain Service JVMCI service} that provides access to a {@link NativeFunctionInterface}
+ * implementation.
+ */
+public interface NativeFunctionInterfaceAccess extends Service {
+
+    /**
+     * Gets the {@link NativeFunctionInterface} implementation available via this access object.
+     */
+    NativeFunctionInterface getNativeFunctionInterface();
+}
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java	Sun May 31 23:57:57 2015 +0200
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java	Sun May 31 23:58:09 2015 +0200
@@ -26,6 +26,7 @@
 
 import java.security.*;
 
+import com.oracle.jvmci.service.*;
 import com.oracle.truffle.api.impl.*;
 
 /**
@@ -36,14 +37,8 @@
     private static final TruffleRuntime RUNTIME = initRuntime();
 
     /**
-     * Creates a new {@link TruffleRuntime} instance if the runtime has a specialized
-     * implementation.
-     *
-     * @throws UnsatisfiedLinkError if the runtime does not have a specialized implementation of
-     *             {@link TruffleRuntime}
+     * Gets the singleton {@link TruffleRuntime} object.
      */
-    private static native TruffleRuntime createRuntime();
-
     public static TruffleRuntime getRuntime() {
         return RUNTIME;
     }
@@ -57,14 +52,14 @@
             return new DefaultTruffleRuntime();
         }
 
-        try {
-            return AccessController.doPrivileged(new PrivilegedAction<TruffleRuntime>() {
-                public TruffleRuntime run() {
-                    return createRuntime();
+        return AccessController.doPrivileged(new PrivilegedAction<TruffleRuntime>() {
+            public TruffleRuntime run() {
+                TruffleRuntimeAccess access = Services.loadSingle(TruffleRuntimeAccess.class, false);
+                if (access != null) {
+                    return access.getRuntime();
                 }
-            });
-        } catch (UnsatisfiedLinkError e) {
-            return new DefaultTruffleRuntime();
-        }
+                return new DefaultTruffleRuntime();
+            }
+        });
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntimeAccess.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.truffle.api;
+
+import com.oracle.jvmci.service.*;
+
+/**
+ * A {@linkplain Service JVMCI service} that provides access to a {@link TruffleRuntime}
+ * implementation.
+ */
+public interface TruffleRuntimeAccess extends Service {
+
+    /**
+     * Gets the {@link TruffleRuntime} implementation available via this access object.
+     */
+    TruffleRuntime getRuntime();
+}
--- a/make/defs.make	Sun May 31 23:57:57 2015 +0200
+++ b/make/defs.make	Sun May 31 23:58:09 2015 +0200
@@ -369,7 +369,7 @@
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.hotspot.HotSpotVMEventListener
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.debug.DebugInitializationPropertyProvider
 
-EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.api.runtime.GraalRuntimeFactory
+EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.api.runtime.GraalRuntimeAccess
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.compiler.match.MatchStatementSet
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.hotspot.HotSpotBackendFactory
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.nodes.spi.ReplacementsProvider
@@ -377,6 +377,9 @@
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.truffle.hotspot.nfi.RawNativeCallNodeFactory
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.truffle.OptimizedCallTargetInstrumentationFactory
 
+EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.truffle.api.TruffleRuntimeAccess
+EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.nfi.api.NativeFunctionInterfaceAccess
+
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotConstantReflectionProvider
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime
 EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaFieldImpl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mx/FilterTypes.java	Sun May 31 23:58:09 2015 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class FilterTypes {
+
+    /**
+     * Prints to {@link System#out} the values in {@code args[1 .. N]} that denote classes that are
+     * {@link Class#isAssignableFrom(Class) assignable} to the type denoted in {@code args[0]}. The
+     * values are separated by {@code "|"}.
+     */
+    public static void main(String... args) throws Exception {
+        Class<?> jvmciServiceInterface = Class.forName(args[0]);
+        boolean needSep = false;
+        StringBuilder buf = new StringBuilder();
+        for (int i = 1; i < args.length; ++i) {
+            String serviceName = args[i];
+            Class<?> service = Class.forName(serviceName, false, FilterTypes.class.getClassLoader());
+            if (jvmciServiceInterface.isAssignableFrom(service)) {
+                if (buf.length() != 0) {
+                    buf.append('|');
+                }
+                buf.append(serviceName);
+                needSep = true;
+            }
+        }
+        System.out.print(buf);
+    }
+}
--- a/mx/mx_graal.py	Sun May 31 23:57:57 2015 +0200
+++ b/mx/mx_graal.py	Sun May 31 23:58:09 2015 +0200
@@ -547,78 +547,20 @@
         shutil.move(tmp, dstLib)
         os.chmod(dstLib, permissions)
 
-def _eraseGenerics(className):
-    if '<' in className:
-        return className[:className.index('<')]
-    return className
-
-def _classifyJVMCIServices(classNames, jvmciJars):
-    classification = {}
-    if not classNames:
-        return classification
-    for className in classNames:
-        classification[className] = None
-    javap = mx.java().javap
-    output = subprocess.check_output([javap, '-cp', os.pathsep.join(jvmciJars)] + classNames, stderr=subprocess.STDOUT)
-    lines = output.split(os.linesep)
-    for line in lines:
-        if line.startswith('public interface '):
-            declLine = line[len('public interface '):].strip()
-            for className in classNames:
-                if declLine.startswith(className):
-                    assert classification[className] is None
-                    afterName = declLine[len(className):]
-                    if not afterName.startswith(' extends '):
-                        classification[className] = False
-                        break
-                    superInterfaces = afterName[len(' extends '):-len(' {')].split(',')
-                    if 'com.oracle.jvmci.service.Service' in superInterfaces:
-                        classification[className] = True
-                        break
-                    maybe = [_eraseGenerics(superInterface) for superInterface in superInterfaces]
-                    classification[className] = maybe
-                    break
-    for className, v in classification.items():
-        if v is None:
-            mx.abort('Could not find interface for service ' + className + ':\n' + output)
-    return classification
-
-def _extractMaybes(classification):
-    maybes = set()
-    for v in classification.values():
-        if isinstance(v, list):
-            maybes.update(v)
-    return list(maybes)
-
-def _mergeClassification(classification, newClassification):
-    for className, value in classification.items():
-        if isinstance(value, list):
-            classification[className] = None
-            for superInterface in value:
-                if newClassification[superInterface] is True:
-                    classification[className] = True
-                    break
-                elif newClassification[superInterface] is False:
-                    if classification[className] is None:
-                        classification[className] = False
-                else:
-                    if not classification[className]:
-                        classification[className] = []
-                    classification[className].extend(newClassification[superInterface])
-
-def _filterJVMCIService(classNames, jvmciJars):
-    classification = _classifyJVMCIServices(classNames, jvmciJars)
-    needClassification = _extractMaybes(classification)
-    while needClassification:
-        _mergeClassification(classification, _classifyJVMCIServices(needClassification, jvmciJars))
-        needClassification = _extractMaybes(classification)
-    filtered = []
-    for className in classNames:
-        if classification[className] is True:
-            filtered.append(className)
-    return filtered
-
-def _extractJVMCIFiles(jvmciJars, servicesDir, optionsDir, cleanDestination=True):
+def _filterJVMCIServices(serviceImplNames, classpath):
+    """
+    Filters and returns the names in 'serviceImplNames' that denote
+    types available in 'classpath' implementing or extending
+    com.oracle.jvmci.service.Service.
+    """
+    _, binDir = mx._compile_mx_class('FilterTypes', os.pathsep.join(classpath), myDir=dirname(__file__))
+    cmd = [mx.java().java, '-cp', mx._cygpathU2W(os.pathsep.join([binDir] + classpath)), 'FilterTypes', 'com.oracle.jvmci.service.Service'] + serviceImplNames
+    services = subprocess.check_output(cmd, stderr=subprocess.PIPE)
+    if len(services) == 0:
+        return []
+    return services.split('|')
+
+def _extractJVMCIFiles(jdkJars, jvmciJars, servicesDir, optionsDir, cleanDestination=True):
     if cleanDestination:
         if exists(servicesDir):
             shutil.rmtree(servicesDir)
@@ -653,7 +595,7 @@
                         with zf.open(member) as optionsFile, \
                              file(targetpath, "wb") as target:
                             shutil.copyfileobj(optionsFile, target)
-    jvmciServices = _filterJVMCIService(servicesMap.keys(), jvmciJars)
+    jvmciServices = _filterJVMCIServices(servicesMap.keys(), jdkJars)
     for serviceName in jvmciServices:
         serviceImpls = servicesMap[serviceName]
         fd, tmp = tempfile.mkstemp(prefix=serviceName)
@@ -672,7 +614,7 @@
     jvmciJars = [join(jreJVMCIDir, e) for e in os.listdir(jreJVMCIDir) if e.endswith('.jar')]
     jreGraalServicesDir = join(jreJVMCIDir, 'services')
     jreGraalOptionsDir = join(jreJVMCIDir, 'options')
-    _extractJVMCIFiles(jvmciJars, jreGraalServicesDir, jreGraalOptionsDir)
+    _extractJVMCIFiles(_getJdkDeployedJars(jdkDir), jvmciJars, jreGraalServicesDir, jreGraalOptionsDir)
 
 def _patchGraalVersionConstant(dist):
     """
@@ -732,6 +674,24 @@
                     # deploy service files
                     _updateJVMCIFiles(jdkDir)
 
+def _getJdkDeployedJars(jdkDir):
+    """
+    Gets jar paths for all deployed distributions in the context of
+    a given JDK directory.
+    """
+    jreLibDir = join(jdkDir, 'jre', 'lib')
+    jars = []
+    for dist in _jdkDeployedDists:
+        jar = basename(mx.distribution(dist.name).path)
+        if dist.isExtension:
+            jars.append(join(jreLibDir, 'ext', jar))
+        elif dist.usesJVMCIClassLoader:
+            jars.append(join(jreLibDir, 'jvmci', jar))
+        else:
+            jars.append(join(jreLibDir, jar))
+    return jars
+
+
 # run a command in the windows SDK Debug Shell
 def _runInDebugShell(cmd, workingDir, logFile=None, findInOutput=None, respondTo=None):
     if respondTo is None:
@@ -892,8 +852,10 @@
         with open(defsPath) as fp:
             defs = fp.read()
         jvmciJars = []
+        jdkJars = []
         for jdkDist in _jdkDeployedDists:
             dist = mx.distribution(jdkDist.name)
+            jdkJars.append(join(_graal_home, dist.path))
             defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/' + basename(dist.path)
             if jdkDist.isExtension:
                 defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_EXT_DIR)/' + basename(dist.path)
@@ -905,7 +867,7 @@
             if defLine not in defs:
                 mx.abort('Missing following line in ' + defsPath + '\n' + defLine)
             shutil.copy(dist.path, opts2.export_dir)
-        services, optionsFiles = _extractJVMCIFiles(jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options'))
+        services, optionsFiles = _extractJVMCIFiles(jdkJars, jvmciJars, join(opts2.export_dir, 'services'), join(opts2.export_dir, 'options'))
         for service in services:
             defLine = 'EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/' + service
             if defLine not in defs:
--- a/mx/suite.py	Sun May 31 23:57:57 2015 +0200
+++ b/mx/suite.py	Sun May 31 23:58:09 2015 +0200
@@ -203,7 +203,7 @@
     "com.oracle.nfi" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],
-      "dependencies" : [],
+      "dependencies" : ["com.oracle.jvmci.service"],
       "checkstyle" : "com.oracle.graal.graph",
       "javaCompliance" : "1.7",
     },
@@ -992,7 +992,7 @@
     "com.oracle.truffle.api" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],
-      "dependencies" : [],
+      "dependencies" : ["com.oracle.jvmci.service"],
       "javaCompliance" : "1.7",
       "workingSets" : "API,Truffle",
     },
@@ -1302,6 +1302,9 @@
         "com.oracle.truffle.interop",
         "com.oracle.truffle.object.basic",
       ],
+      "distDependencies" : [
+        "JVMCI_SERVICE",
+      ],
     },
 
     "GRAAL_TRUFFLE" : {
--- a/mxtool/mx.py	Sun May 31 23:57:57 2015 +0200
+++ b/mxtool/mx.py	Sun May 31 23:58:09 2015 +0200
@@ -5434,8 +5434,8 @@
         _show_section('projects', s.projects)
         _show_section('distributions', s.dists)
 
-def _compile_mx_class(javaClassName, classpath=None, jdk=None):
-    myDir = dirname(__file__)
+def _compile_mx_class(javaClassName, classpath=None, jdk=None, myDir=None):
+    myDir = dirname(__file__) if myDir is None else myDir
     binDir = join(myDir, 'bin' if not jdk else '.jdk' + str(jdk.version))
     javaSource = join(myDir, javaClassName + '.java')
     javaClass = join(binDir, javaClassName + '.class')
--- a/src/share/vm/jvmci/jvmciRuntime.cpp	Sun May 31 23:57:57 2015 +0200
+++ b/src/share/vm/jvmci/jvmciRuntime.cpp	Sun May 31 23:58:09 2015 +0200
@@ -644,32 +644,6 @@
   return JNIHandles::make_local(THREAD, JVMCIRuntime::get_service_impls(serviceKlass, THREAD)());
 JVM_END
 
-// private static TruffleRuntime Truffle.createRuntime()
-JVM_ENTRY(jobject, JVM_CreateTruffleRuntime(JNIEnv *env, jclass c))
-  JVMCIRuntime::ensure_jvmci_class_loader_is_initialized();
-  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", CHECK_NULL);
-  KlassHandle klass = JVMCIRuntime::resolve_or_fail(name, CHECK_NULL);
-
-  TempNewSymbol makeInstance = SymbolTable::new_symbol("makeInstance", CHECK_NULL);
-  TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/truffle/api/TruffleRuntime;", CHECK_NULL);
-  JavaValue result(T_OBJECT);
-  JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
-JVM_END
-
-// private static NativeFunctionInterfaceRuntime.createInterface()
-JVM_ENTRY(jobject, JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c))
-  JVMCIRuntime::ensure_jvmci_class_loader_is_initialized();
-  TempNewSymbol name = SymbolTable::new_symbol("com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime", CHECK_NULL);
-  KlassHandle klass = JVMCIRuntime::resolve_or_fail(name, CHECK_NULL);
-
-  TempNewSymbol makeInstance = SymbolTable::new_symbol("createNativeFunctionInterface", CHECK_NULL);
-  TempNewSymbol sig = SymbolTable::new_symbol("()Lcom/oracle/nfi/api/NativeFunctionInterface;", CHECK_NULL);
-  JavaValue result(T_OBJECT);
-  JavaCalls::call_static(&result, klass, makeInstance, sig, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, (oop) result.get_jobject());
-JVM_END
-
 Handle JVMCIRuntime::callInitializer(const char* className, const char* methodName, const char* returnType) {
   guarantee(!_HotSpotJVMCIRuntime_initialized, "cannot reinitialize HotSpotJVMCIRuntime");
   Thread* THREAD = Thread::current();
--- a/src/share/vm/prims/nativeLookup.cpp	Sun May 31 23:57:57 2015 +0200
+++ b/src/share/vm/prims/nativeLookup.cpp	Sun May 31 23:58:09 2015 +0200
@@ -132,11 +132,6 @@
   jobject  JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
   jobject  JNICALL JVM_GetJVMCIRuntime(JNIEnv *env, jclass c);
   jobject  JNICALL JVM_GetJVMCIServiceImpls(JNIEnv *env, jclass c, jclass serviceClass);
-  jobject  JNICALL JVM_CreateTruffleRuntime(JNIEnv *env, jclass c);
-  jobject  JNICALL JVM_CreateNativeFunctionInterface(JNIEnv *env, jclass c);
-#ifdef COMPILERJVMCI
-  void     JNICALL JVM_PrintAndResetJVMCICompRate(JNIEnv *env, jclass c);
-#endif
 #endif
 }
 
@@ -152,8 +147,6 @@
   { CC"Java_com_oracle_jvmci_service_JVMCIClassLoaderFactory_init",            NULL, FN_PTR(JVM_InitJVMCIClassLoader)               },
   { CC"Java_com_oracle_jvmci_runtime_JVMCI_initializeRuntime",                 NULL, FN_PTR(JVM_GetJVMCIRuntime)                    },
   { CC"Java_com_oracle_jvmci_service_Services_getServiceImpls",                NULL, FN_PTR(JVM_GetJVMCIServiceImpls)               },
-  { CC"Java_com_oracle_truffle_api_Truffle_createRuntime",                     NULL, FN_PTR(JVM_CreateTruffleRuntime)               },
-  { CC"Java_com_oracle_nfi_NativeFunctionInterfaceRuntime_createInterface",    NULL, FN_PTR(JVM_CreateNativeFunctionInterface)      },
   { CC"Java_com_oracle_jvmci_hotspot_CompilerToVMImpl_init",                   NULL, FN_PTR(JVM_InitializeJVMCINatives)             },
 #endif
 };