8167180: [JVMCI] Exported elements referring to inaccessible types in jdk.vm.ci
authordnsimon
Tue, 11 Oct 2016 00:08:20 +0200
changeset 41725 5aef0bf3bef7
parent 41719 d2a206359a7b
child 41726 e0747416c678
8167180: [JVMCI] Exported elements referring to inaccessible types in jdk.vm.ci Reviewed-by: mchung, twisti, alanb
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.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/HotSpotVMEventListener.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EmptyEventProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EventProvider.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotJVMCICompilerFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java
hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java
hotspot/src/jdk.vm.ci/share/classes/module-info.java
hotspot/test/compiler/jvmci/common/JVMCIHelpers.java
hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener
hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompiler
hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.services.JVMCICompilerFactory
hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.config
hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java
hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.config
hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java
hotspot/test/compiler/jvmci/events/JvmciShutdownEventListener.java
hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.config
hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EmptyEventProvider.java	Tue Oct 11 00:08:20 2016 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+/**
+ * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
+ * requested.
+ */
+final class EmptyEventProvider implements EventProvider {
+
+    static InternalError shouldNotReachHere() {
+        throw new InternalError("should not reach here");
+    }
+
+    @Override
+    public CompilationEvent newCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    static class EmptyCompilationEvent implements CompilationEvent {
+        public void commit() {
+            throw shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void begin() {
+        }
+
+        public void end() {
+        }
+
+        public void setMethod(String method) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCompileId(int compileId) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCompileLevel(int compileLevel) {
+            throw shouldNotReachHere();
+        }
+
+        public void setSucceeded(boolean succeeded) {
+            throw shouldNotReachHere();
+        }
+
+        public void setIsOsr(boolean isOsr) {
+            throw shouldNotReachHere();
+        }
+
+        public void setCodeSize(int codeSize) {
+            throw shouldNotReachHere();
+        }
+
+        public void setInlinedBytes(int inlinedBytes) {
+            throw shouldNotReachHere();
+        }
+    }
+
+    @Override
+    public CompilerFailureEvent newCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
+        public void commit() {
+            throw shouldNotReachHere();
+        }
+
+        public boolean shouldWrite() {
+            // Events of this class should never been written.
+            return false;
+        }
+
+        public void setCompileId(int compileId) {
+            throw shouldNotReachHere();
+        }
+
+        public void setMessage(String message) {
+            throw shouldNotReachHere();
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/EventProvider.java	Tue Oct 11 00:08:20 2016 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2014, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilationEvent;
+import jdk.vm.ci.hotspot.EmptyEventProvider.EmptyCompilerFailureEvent;
+import jdk.vm.ci.services.JVMCIPermission;
+
+/**
+ * Service-provider class for logging compiler related events.
+ */
+public interface EventProvider {
+
+    /**
+     * Creates and returns an empty implementation for {@link EventProvider}. This implementation
+     * can be used when no logging is requested.
+     */
+    static EventProvider createEmptyEventProvider() {
+        return new EmptyEventProvider();
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link CompilationEvent}.
+     */
+    static CompilationEvent createEmptyCompilationEvent() {
+        return new EmptyCompilationEvent();
+    }
+
+    /**
+     * Creates and returns an empty implementation for {@link CompilationEvent}.
+     */
+    static CompilerFailureEvent createEmptyCompilerFailureEvent() {
+        return new EmptyCompilerFailureEvent();
+    }
+
+    /**
+     * An instant event is an event that is not considered to have taken any time.
+     */
+    public interface InstantEvent {
+        /**
+         * Commits the event.
+         */
+        void commit();
+
+        /**
+         * Determines if this particular event instance would be committed to the data stream right
+         * now if application called {@link #commit()}. This in turn depends on whether the event is
+         * enabled and possible other factors.
+         *
+         * @return if this event would be committed on a call to {@link #commit()}.
+         */
+        boolean shouldWrite();
+    }
+
+    /**
+     * Timed events describe an operation that somehow consumes time.
+     */
+    public interface TimedEvent extends InstantEvent {
+        /**
+         * Starts the timing for this event.
+         */
+        void begin();
+
+        /**
+         * Ends the timing period for this event.
+         */
+        void end();
+    }
+
+    /**
+     * Creates a new {@link CompilationEvent}.
+     *
+     * @return a compilation event
+     */
+    public abstract CompilationEvent newCompilationEvent();
+
+    /**
+     * A compilation event.
+     */
+    public interface CompilationEvent extends TimedEvent {
+        void setMethod(String method);
+
+        void setCompileId(int compileId);
+
+        void setCompileLevel(int compileLevel);
+
+        void setSucceeded(boolean succeeded);
+
+        void setIsOsr(boolean isOsr);
+
+        void setCodeSize(int codeSize);
+
+        void setInlinedBytes(int inlinedBytes);
+    }
+
+    /**
+     * Creates a new {@link CompilerFailureEvent}.
+     *
+     * @return a compiler failure event
+     */
+    public abstract CompilerFailureEvent newCompilerFailureEvent();
+
+    /**
+     * A compiler failure event.
+     */
+    public interface CompilerFailureEvent extends InstantEvent {
+        void setCompileId(int compileId);
+
+        void setMessage(String message);
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerConfig.java	Tue Oct 11 00:08:20 2016 +0200
@@ -26,8 +26,10 @@
 import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option;
 import jdk.vm.ci.runtime.JVMCICompiler;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
 import jdk.vm.ci.runtime.JVMCIRuntime;
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+import jdk.vm.ci.services.JVMCIServiceLocator;
+import jdk.vm.ci.services.JVMCIPermission;
 import jdk.vm.ci.services.Services;
 
 final class HotSpotJVMCICompilerConfig {
@@ -37,7 +39,7 @@
      * to perform a compilation. This allows the reflective parts of the JVMCI API to be used
      * without requiring a compiler implementation to be available.
      */
-    private static class DummyCompilerFactory extends JVMCICompilerFactory implements JVMCICompiler {
+    private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler {
 
         public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) {
             throw new JVMCIError("no JVMCI compiler selected");
@@ -63,15 +65,16 @@
      * Gets the selected system compiler factory.
      *
      * @return the selected system compiler factory
+     * @throws SecurityException if a security manager is present and it denies
+     *             {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method
      */
     static JVMCICompilerFactory getCompilerFactory() {
         if (compilerFactory == null) {
             JVMCICompilerFactory factory = null;
             String compilerName = Option.Compiler.getString();
             if (compilerName != null) {
-                for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
+                for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) {
                     if (f.getCompilerName().equals(compilerName)) {
-                        Services.exportJVMCITo(f.getClass());
                         factory = f;
                     }
                 }
@@ -80,7 +83,7 @@
                 }
             } else {
                 // Auto select a single available compiler
-                for (JVMCICompilerFactory f : Services.load(JVMCICompilerFactory.class)) {
+                for (JVMCICompilerFactory f : JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class)) {
                     if (factory == null) {
                         Services.exportJVMCITo(f.getClass());
                         factory = f;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCICompilerFactory.java	Tue Oct 11 00:08:20 2016 +0200
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2016, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
+
+/**
+ * HotSpot extensions to {@link JVMCICompilerFactory}.
+ */
+public abstract class HotSpotJVMCICompilerFactory implements JVMCICompilerFactory {
+
+    /**
+     * Gets 0 or more prefixes identifying classes that should by compiled by C1 in simple mode
+     * (i.e., {@code CompLevel_simple}) when HotSpot is running with tiered compilation. The
+     * prefixes should be class or package names using "/" as the separator, e.g. "jdk/vm/ci".
+     *
+     * @return 0 or more Strings identifying packages that should by compiled by the first tier only
+     *         or null if no redirection to C1 should be performed.
+     */
+    public String[] getTrivialPrefixes() {
+        return null;
+    }
+
+    public enum CompilationLevelAdjustment {
+        /**
+         * No adjustment.
+         */
+        None,
+
+        /**
+         * Adjust based on declaring class of method.
+         */
+        ByHolder,
+
+        /**
+         * Adjust based on declaring class, name and signature of method.
+         */
+        ByFullSignature
+    }
+
+    /**
+     * Determines if this object may want to adjust the compilation level for a method that is being
+     * scheduled by the VM for compilation.
+     */
+    public CompilationLevelAdjustment getCompilationLevelAdjustment() {
+        return CompilationLevelAdjustment.None;
+    }
+
+    public enum CompilationLevel {
+        None,
+        Simple,
+        LimitedProfile,
+        FullProfile,
+        FullOptimization
+    }
+
+    /**
+     * Potentially modifies the compilation level currently selected by the VM compilation policy
+     * for a method.
+     *
+     * @param declaringClass the class in which the method is declared
+     * @param name the name of the method or {@code null} depending on the value that was returned
+     *            by {@link #getCompilationLevelAdjustment()}
+     * @param signature the signature of the method or {@code null} depending on the value that was
+     *            returned by {@link #getCompilationLevelAdjustment()}
+     * @param isOsr specifies if the compilation being scheduled in an OSR compilation
+     * @param level the compilation level currently selected by the VM compilation policy
+     * @return the compilation level to use for the compilation being scheduled (must be a valid
+     *         {@code CompLevel} enum value)
+     */
+    public CompilationLevel adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, CompilationLevel level) {
+        throw new InternalError("Should not reach here");
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java	Tue Oct 11 00:08:20 2016 +0200
@@ -27,13 +27,11 @@
 import java.io.IOException;
 import java.io.OutputStream;
 import java.io.PrintStream;
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.ServiceLoader;
 import java.util.TreeMap;
 
 import jdk.internal.misc.VM;
@@ -43,16 +41,15 @@
 import jdk.vm.ci.code.InstalledCode;
 import jdk.vm.ci.common.InitTimer;
 import jdk.vm.ci.common.JVMCIError;
-import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory;
-import jdk.vm.ci.hotspot.services.HotSpotJVMCICompilerFactory.CompilationLevel;
-import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.HotSpotJVMCICompilerFactory.CompilationLevel;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaType;
 import jdk.vm.ci.runtime.JVMCI;
 import jdk.vm.ci.runtime.JVMCIBackend;
 import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
+import jdk.vm.ci.services.JVMCIServiceLocator;
 import jdk.vm.ci.services.Services;
 
 /**
@@ -246,11 +243,7 @@
         if (vmEventListeners == null) {
             synchronized (this) {
                 if (vmEventListeners == null) {
-                    List<HotSpotVMEventListener> listeners = new ArrayList<>();
-                    for (HotSpotVMEventListener vmEventListener : ServiceLoader.load(HotSpotVMEventListener.class)) {
-                        listeners.add(vmEventListener);
-                    }
-                    vmEventListeners = listeners;
+                    vmEventListeners = JVMCIServiceLocator.getProviders(HotSpotVMEventListener.class);
                 }
             }
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotVMEventListener.java	Tue Oct 11 00:08:20 2016 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2015, 2016, 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 jdk.vm.ci.hotspot;
+
+import jdk.vm.ci.code.CompiledCode;
+import jdk.vm.ci.code.InstalledCode;
+
+/**
+ * Listener for responding to VM events.
+ */
+public interface HotSpotVMEventListener {
+
+    /**
+     * Notifies this client that the VM is shutting down.
+     */
+    default void notifyShutdown() {
+    }
+
+    /**
+     * Notify on successful install into the code cache.
+     *
+     * @param hotSpotCodeCacheProvider the code cache into which the code was installed
+     * @param installedCode the code that was installed
+     * @param compiledCode the compiled code from which {@code installedCode} was produced
+     */
+    default void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
+    }
+
+    /**
+     * Notify on completion of a bootstrap.
+     */
+    default void notifyBootstrapFinished() {
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EmptyEventProvider.java	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-/*
- * Copyright (c) 2014, 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 jdk.vm.ci.hotspot.services;
-
-/**
- * An empty implementation for {@link EventProvider}. This implementation is used when no logging is
- * requested.
- */
-final class EmptyEventProvider extends EventProvider {
-
-    EmptyEventProvider() {
-        super(null);
-    }
-
-    static InternalError shouldNotReachHere() {
-        throw new InternalError("should not reach here");
-    }
-
-    @Override
-    public CompilationEvent newCompilationEvent() {
-        return new EmptyCompilationEvent();
-    }
-
-    static class EmptyCompilationEvent implements CompilationEvent {
-        public void commit() {
-            throw shouldNotReachHere();
-        }
-
-        public boolean shouldWrite() {
-            // Events of this class should never been written.
-            return false;
-        }
-
-        public void begin() {
-        }
-
-        public void end() {
-        }
-
-        public void setMethod(String method) {
-            throw shouldNotReachHere();
-        }
-
-        public void setCompileId(int compileId) {
-            throw shouldNotReachHere();
-        }
-
-        public void setCompileLevel(int compileLevel) {
-            throw shouldNotReachHere();
-        }
-
-        public void setSucceeded(boolean succeeded) {
-            throw shouldNotReachHere();
-        }
-
-        public void setIsOsr(boolean isOsr) {
-            throw shouldNotReachHere();
-        }
-
-        public void setCodeSize(int codeSize) {
-            throw shouldNotReachHere();
-        }
-
-        public void setInlinedBytes(int inlinedBytes) {
-            throw shouldNotReachHere();
-        }
-    }
-
-    @Override
-    public CompilerFailureEvent newCompilerFailureEvent() {
-        return new EmptyCompilerFailureEvent();
-    }
-
-    static class EmptyCompilerFailureEvent implements CompilerFailureEvent {
-        public void commit() {
-            throw shouldNotReachHere();
-        }
-
-        public boolean shouldWrite() {
-            // Events of this class should never been written.
-            return false;
-        }
-
-        public void setCompileId(int compileId) {
-            throw shouldNotReachHere();
-        }
-
-        public void setMessage(String message) {
-            throw shouldNotReachHere();
-        }
-    }
-
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/EventProvider.java	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright (c) 2014, 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 jdk.vm.ci.hotspot.services;
-
-import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilationEvent;
-import jdk.vm.ci.hotspot.services.EmptyEventProvider.EmptyCompilerFailureEvent;
-import jdk.vm.ci.services.JVMCIPermission;
-
-/**
- * Service-provider class for logging compiler related events.
- */
-public abstract class EventProvider {
-
-    private static Void checkPermission() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new JVMCIPermission());
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    EventProvider(Void ignore) {
-    }
-
-    /**
-     * Initializes a new instance of this class.
-     *
-     * @throws SecurityException if a security manager has been installed and it denies
-     *             {@link JVMCIPermission}
-     */
-    protected EventProvider() {
-        this(checkPermission());
-    }
-
-    /**
-     * Creates and returns an empty implementation for {@link EventProvider}. This implementation
-     * can be used when no logging is requested.
-     */
-    public static EventProvider createEmptyEventProvider() {
-        return new EmptyEventProvider();
-    }
-
-    /**
-     * Creates and returns an empty implementation for {@link CompilationEvent}.
-     */
-    public static CompilationEvent createEmptyCompilationEvent() {
-        return new EmptyCompilationEvent();
-    }
-
-    /**
-     * Creates and returns an empty implementation for {@link CompilationEvent}.
-     */
-    public static CompilerFailureEvent createEmptyCompilerFailureEvent() {
-        return new EmptyCompilerFailureEvent();
-    }
-
-    /**
-     * An instant event is an event that is not considered to have taken any time.
-     */
-    public interface InstantEvent {
-        /**
-         * Commits the event.
-         */
-        void commit();
-
-        /**
-         * Determines if this particular event instance would be committed to the data stream right
-         * now if application called {@link #commit()}. This in turn depends on whether the event is
-         * enabled and possible other factors.
-         *
-         * @return if this event would be committed on a call to {@link #commit()}.
-         */
-        boolean shouldWrite();
-    }
-
-    /**
-     * Timed events describe an operation that somehow consumes time.
-     */
-    public interface TimedEvent extends InstantEvent {
-        /**
-         * Starts the timing for this event.
-         */
-        void begin();
-
-        /**
-         * Ends the timing period for this event.
-         */
-        void end();
-    }
-
-    /**
-     * Creates a new {@link CompilationEvent}.
-     *
-     * @return a compilation event
-     */
-    public abstract CompilationEvent newCompilationEvent();
-
-    /**
-     * A compilation event.
-     */
-    public interface CompilationEvent extends TimedEvent {
-        void setMethod(String method);
-
-        void setCompileId(int compileId);
-
-        void setCompileLevel(int compileLevel);
-
-        void setSucceeded(boolean succeeded);
-
-        void setIsOsr(boolean isOsr);
-
-        void setCodeSize(int codeSize);
-
-        void setInlinedBytes(int inlinedBytes);
-    }
-
-    /**
-     * Creates a new {@link CompilerFailureEvent}.
-     *
-     * @return a compiler failure event
-     */
-    public abstract CompilerFailureEvent newCompilerFailureEvent();
-
-    /**
-     * A compiler failure event.
-     */
-    public interface CompilerFailureEvent extends InstantEvent {
-        void setCompileId(int compileId);
-
-        void setMessage(String message);
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotJVMCICompilerFactory.java	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2016, 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 jdk.vm.ci.hotspot.services;
-
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
-
-/**
- * HotSpot extensions to {@link JVMCICompilerFactory}.
- */
-public abstract class HotSpotJVMCICompilerFactory extends JVMCICompilerFactory {
-
-    /**
-     * Gets 0 or more prefixes identifying classes that should by compiled by C1 in simple mode
-     * (i.e., {@code CompLevel_simple}) when HotSpot is running with tiered compilation. The
-     * prefixes should be class or package names using "/" as the separator, e.g. "jdk/vm/ci".
-     *
-     * @return 0 or more Strings identifying packages that should by compiled by the first tier only
-     *         or null if no redirection to C1 should be performed.
-     */
-    public String[] getTrivialPrefixes() {
-        return null;
-    }
-
-    public enum CompilationLevelAdjustment {
-        /**
-         * No adjustment.
-         */
-        None,
-
-        /**
-         * Adjust based on declaring class of method.
-         */
-        ByHolder,
-
-        /**
-         * Adjust based on declaring class, name and signature of method.
-         */
-        ByFullSignature
-    }
-
-    /**
-     * Determines if this object may want to adjust the compilation level for a method that is being
-     * scheduled by the VM for compilation.
-     */
-    public CompilationLevelAdjustment getCompilationLevelAdjustment() {
-        return CompilationLevelAdjustment.None;
-    }
-
-    public enum CompilationLevel {
-        None,
-        Simple,
-        LimitedProfile,
-        FullProfile,
-        FullOptimization
-    }
-
-    /**
-     * Potentially modifies the compilation level currently selected by the VM compilation policy
-     * for a method.
-     *
-     * @param declaringClass the class in which the method is declared
-     * @param name the name of the method or {@code null} depending on the value that was returned
-     *            by {@link #getCompilationLevelAdjustment()}
-     * @param signature the signature of the method or {@code null} depending on the value that was
-     *            returned by {@link #getCompilationLevelAdjustment()}
-     * @param isOsr specifies if the compilation being scheduled in an OSR compilation
-     * @param level the compilation level currently selected by the VM compilation policy
-     * @return the compilation level to use for the compilation being scheduled (must be a valid
-     *         {@code CompLevel} enum value)
-     */
-    public CompilationLevel adjustCompilationLevel(Class<?> declaringClass, String name, String signature, boolean isOsr, CompilationLevel level) {
-        throw new InternalError("Should not reach here");
-    }
-}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/services/HotSpotVMEventListener.java	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/*
- * Copyright (c) 2015, 2016, 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 jdk.vm.ci.hotspot.services;
-
-import jdk.vm.ci.code.CompiledCode;
-import jdk.vm.ci.code.InstalledCode;
-import jdk.vm.ci.hotspot.HotSpotCodeCacheProvider;
-import jdk.vm.ci.services.JVMCIPermission;
-
-/**
- * Service-provider class for responding to VM events.
- */
-public abstract class HotSpotVMEventListener {
-
-    private static Void checkPermission() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new JVMCIPermission());
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    HotSpotVMEventListener(Void ignore) {
-    }
-
-    /**
-     * Initializes a new instance of this class.
-     *
-     * @throws SecurityException if a security manager has been installed and it denies
-     *             {@link JVMCIPermission}
-     */
-    protected HotSpotVMEventListener() {
-        this(checkPermission());
-    }
-
-    /**
-     * Notifies this client that the VM is shutting down.
-     */
-    public void notifyShutdown() {
-    }
-
-    /**
-     * Notify on successful install into the code cache.
-     *
-     * @param hotSpotCodeCacheProvider
-     * @param installedCode
-     * @param compiledCode
-     */
-    public void notifyInstall(HotSpotCodeCacheProvider hotSpotCodeCacheProvider, InstalledCode installedCode, CompiledCode compiledCode) {
-    }
-
-    /**
-     * Notify on completion of a bootstrap.
-     */
-    public void notifyBootstrapFinished() {
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/JVMCICompilerFactory.java	Tue Oct 11 00:08:20 2016 +0200
@@ -0,0 +1,57 @@
+/*
+ * 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 jdk.vm.ci.runtime;
+
+import java.io.PrintStream;
+
+/**
+ * Factory for creating JVMCI compilers.
+ */
+public interface JVMCICompilerFactory {
+
+    /**
+     * Get the name of this compiler. The name is used by JVMCI to determine which factory to use.
+     */
+    String getCompilerName();
+
+    /**
+     * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime)
+     * create} a compiler and it should now perform any heavy weight initialization that it deferred
+     * during construction.
+     */
+    default void onSelection() {
+    }
+
+    /**
+     * Create a new instance of a {@link JVMCICompiler}.
+     */
+    JVMCICompiler createCompiler(JVMCIRuntime runtime);
+
+    /**
+     * Prints a description of the properties used to configure this compiler.
+     *
+     * @param out where to print the message
+     */
+    default void printProperties(PrintStream out) {
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.runtime/src/jdk/vm/ci/runtime/services/JVMCICompilerFactory.java	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,83 +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 jdk.vm.ci.runtime.services;
-
-import java.io.PrintStream;
-
-import jdk.vm.ci.runtime.JVMCICompiler;
-import jdk.vm.ci.runtime.JVMCIRuntime;
-import jdk.vm.ci.services.JVMCIPermission;
-
-/**
- * Service-provider class for creating JVMCI compilers.
- */
-public abstract class JVMCICompilerFactory {
-
-    private static Void checkPermission() {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new JVMCIPermission());
-        }
-        return null;
-    }
-
-    @SuppressWarnings("unused")
-    private JVMCICompilerFactory(Void ignore) {
-    }
-
-    /**
-     * Initializes a new instance of this class.
-     *
-     * @throws SecurityException if a security manager has been installed and it denies
-     *             {@link JVMCIPermission}
-     */
-    protected JVMCICompilerFactory() {
-        this(checkPermission());
-    }
-
-    /**
-     * Get the name of this compiler. The name is used by JVMCI to determine which factory to use.
-     */
-    public abstract String getCompilerName();
-
-    /**
-     * Notifies this object that it has been selected to {@linkplain #createCompiler(JVMCIRuntime)
-     * create} a compiler and it should now perform any heavy weight initialization that it deferred
-     * during construction.
-     */
-    public void onSelection() {
-    }
-
-    /**
-     * Create a new instance of a {@link JVMCICompiler}.
-     */
-    public abstract JVMCICompiler createCompiler(JVMCIRuntime runtime);
-
-    /**
-     * Prints a description of the properties used to configure this compiler.
-     *
-     * @param out where to print the message
-     */
-    public void printProperties(PrintStream out) {
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/jdk.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/JVMCIServiceLocator.java	Tue Oct 11 00:08:20 2016 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016, 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 jdk.vm.ci.services;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Service-provider class for the runtime to locate providers of JVMCI services where the latter are
+ * not in packages exported by the JVMCI module. As part of instantiating
+ * {@link JVMCIServiceLocator}, all JVMCI packages will be {@linkplain Services#exportJVMCITo(Class)
+ * exported} to the module defining the class of the instantiated object.
+ *
+ * While the {@link #getProvider(Class)} method can be used directly, it's usually easier to use
+ * {@link #getProviders(Class)}.
+ */
+public abstract class JVMCIServiceLocator {
+
+    private static Void checkPermission() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(new JVMCIPermission());
+        }
+        return null;
+    }
+
+    @SuppressWarnings("unused")
+    private JVMCIServiceLocator(Void ignore) {
+    }
+
+    /**
+     * Creates a capability for accessing JVMCI. Once successfully instantiated, JVMCI exports all
+     * its packages to the module defining the type of this object.
+     *
+     * @throws SecurityException if a security manager has been installed and it denies
+     *             {@link JVMCIPermission}
+     */
+    protected JVMCIServiceLocator() {
+        this(checkPermission());
+        Services.exportJVMCITo(getClass());
+    }
+
+    /**
+     * Gets the provider of the service defined by {@code service} or {@code null} if this object
+     * does not have a provider for {@code service}.
+     */
+    public abstract <S> S getProvider(Class<S> service);
+
+    /**
+     * Gets the providers of the service defined by {@code service} by querying the
+     * {@link JVMCIServiceLocator} providers obtained by {@link Services#load(Class)}.
+     */
+    public static <S> List<S> getProviders(Class<S> service) {
+        List<S> providers = new ArrayList<>();
+        for (JVMCIServiceLocator access : Services.load(JVMCIServiceLocator.class)) {
+            S provider = access.getProvider(service);
+            if (provider != null) {
+                providers.add(provider);
+            }
+        }
+        return providers;
+    }
+}
--- a/hotspot/src/jdk.vm.ci/share/classes/module-info.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/src/jdk.vm.ci/share/classes/module-info.java	Tue Oct 11 00:08:20 2016 +0200
@@ -25,12 +25,9 @@
 
 module jdk.vm.ci {
     exports jdk.vm.ci.services;
-    exports jdk.vm.ci.runtime.services;
-    exports jdk.vm.ci.hotspot.services;
 
-    uses jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+    uses jdk.vm.ci.services.JVMCIServiceLocator;
     uses jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory;
-    uses jdk.vm.ci.runtime.services.JVMCICompilerFactory;
 
     provides jdk.vm.ci.hotspot.HotSpotJVMCIBackendFactory with
         jdk.vm.ci.hotspot.aarch64.AArch64HotSpotJVMCIBackendFactory;
--- a/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/common/JVMCIHelpers.java	Tue Oct 11 00:08:20 2016 +0200
@@ -25,17 +25,29 @@
 
 import jdk.vm.ci.code.CompilationRequest;
 import jdk.vm.ci.code.CompilationRequestResult;
-import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
+import jdk.vm.ci.services.JVMCIServiceLocator;
 import jdk.vm.ci.runtime.JVMCICompiler;
 import jdk.vm.ci.runtime.JVMCIRuntime;
-import jdk.vm.ci.runtime.services.JVMCICompilerFactory;
+import jdk.vm.ci.runtime.JVMCICompilerFactory;
 
 /*
  * A stub classes to be able to use jvmci
  */
-public class JVMCIHelpers {
+public class JVMCIHelpers extends JVMCIServiceLocator {
 
-    public static class EmptyVMEventListener extends HotSpotVMEventListener {
+    @Override
+    public <S> S getProvider(Class<S> service) {
+        if (service == JVMCICompilerFactory.class) {
+            return service.cast(new EmptyCompilerFactory());
+        }
+        if (service == HotSpotVMEventListener.class) {
+            return service.cast(new EmptyVMEventListener());
+        }
+        return null;
+    }
+
+    public static class EmptyVMEventListener implements HotSpotVMEventListener {
         // just empty, using default interface methods
     }
 
@@ -54,7 +66,7 @@
         }
     }
 
-    public static class EmptyCompilerFactory extends JVMCICompilerFactory {
+    public static class EmptyCompilerFactory implements JVMCICompilerFactory {
 
         @Override
         public String getCompilerName() {
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyVMEventListener
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.JVMCICompiler	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
--- a/hotspot/test/compiler/jvmci/common/services/jdk.vm.ci.runtime.services.JVMCICompilerFactory	Tue Oct 18 13:24:02 2016 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
--- a/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.config	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.config	Tue Oct 11 00:08:20 2016 +0200
@@ -1,1 +1,2 @@
 compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest
+compiler.jvmci.common.JVMCIHelpers
--- a/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyBootstrapFinishedEventTest.java	Tue Oct 11 00:08:20 2016 +0200
@@ -37,9 +37,8 @@
  *
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build compiler.jvmci.common.JVMCIHelpers
- * @run driver jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
  * @run driver jdk.test.lib.FileInstaller ./JvmciNotifyBootstrapFinishedEventTest.config
- *     ./META-INF/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener
+ *     ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator
  * @run driver ClassFileInstaller
  *      compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
@@ -60,9 +59,10 @@
 package compiler.jvmci.events;
 
 import jdk.test.lib.Asserts;
-import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+import jdk.vm.ci.services.JVMCIServiceLocator;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
 
-public class JvmciNotifyBootstrapFinishedEventTest extends HotSpotVMEventListener {
+public class JvmciNotifyBootstrapFinishedEventTest extends JVMCIServiceLocator implements HotSpotVMEventListener {
     private static final boolean BOOTSTRAP = Boolean
             .getBoolean("compiler.jvmci.events.JvmciNotifyBootstrapFinishedEventTest.bootstrap");
     private static volatile int gotBoostrapNotification = 0;
@@ -76,6 +76,14 @@
     }
 
     @Override
+    public <S> S getProvider(Class<S> service) {
+        if (service == HotSpotVMEventListener.class) {
+            return service.cast(this);
+        }
+        return null;
+    }
+
+    @Override
     public void notifyBootstrapFinished() {
         gotBoostrapNotification++;
     }
--- a/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.config	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.config	Tue Oct 11 00:08:20 2016 +0200
@@ -1,1 +1,2 @@
 compiler.jvmci.events.JvmciNotifyInstallEventTest
+compiler.jvmci.common.JVMCIHelpers
--- a/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciNotifyInstallEventTest.java	Tue Oct 11 00:08:20 2016 +0200
@@ -38,9 +38,8 @@
  *
  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  * @build compiler.jvmci.common.JVMCIHelpers
- * @run driver jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
  * @run driver jdk.test.lib.FileInstaller ./JvmciNotifyInstallEventTest.config
- *     ./META-INF/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener
+ *     ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator
  * @run driver ClassFileInstaller
  *      compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory
@@ -73,6 +72,7 @@
 import compiler.jvmci.common.testcases.SimpleClass;
 import jdk.test.lib.Asserts;
 import jdk.test.lib.Utils;
+import jdk.vm.ci.services.JVMCIServiceLocator;
 import jdk.vm.ci.code.CompiledCode;
 import jdk.vm.ci.code.InstalledCode;
 import jdk.vm.ci.code.site.DataPatch;
@@ -82,13 +82,13 @@
 import jdk.vm.ci.hotspot.HotSpotCompiledCode.Comment;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
-import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
 import jdk.vm.ci.meta.Assumptions.Assumption;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 import java.lang.reflect.Method;
 
-public class JvmciNotifyInstallEventTest extends HotSpotVMEventListener {
+public class JvmciNotifyInstallEventTest extends JVMCIServiceLocator implements HotSpotVMEventListener {
     private static final String METHOD_NAME = "testMethod";
     private static final boolean FAIL_ON_INIT = !Boolean.getBoolean(
             "compiler.jvmci.events.JvmciNotifyInstallEventTest.failoninit");
@@ -98,6 +98,14 @@
         new JvmciNotifyInstallEventTest().runTest();
     }
 
+    @Override
+    public <S> S getProvider(Class<S> service) {
+        if (service == HotSpotVMEventListener.class) {
+            return service.cast(this);
+        }
+        return null;
+    }
+
     private void runTest() {
         if (gotInstallNotification != 0) {
             throw new Error("Got install notification before test actions");
--- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventListener.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventListener.java	Tue Oct 11 00:08:20 2016 +0200
@@ -23,10 +23,11 @@
 
 package compiler.jvmci.events;
 
+import jdk.vm.ci.services.JVMCIServiceLocator;
 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
-import jdk.vm.ci.hotspot.services.HotSpotVMEventListener;
+import jdk.vm.ci.hotspot.HotSpotVMEventListener;
 
-public class JvmciShutdownEventListener extends HotSpotVMEventListener {
+public class JvmciShutdownEventListener extends JVMCIServiceLocator implements HotSpotVMEventListener {
     public static final String MESSAGE = "Shutdown notified";
     public static final String GOT_INTERNAL_ERROR = "Got internal error";
 
@@ -39,6 +40,14 @@
     }
 
     @Override
+    public <S> S getProvider(Class<S> service) {
+        if (service == HotSpotVMEventListener.class) {
+            return service.cast(this);
+        }
+        return null;
+    }
+
+    @Override
     public void notifyShutdown() {
         System.out.println(MESSAGE);
     }
--- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.config	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.config	Tue Oct 11 00:08:20 2016 +0200
@@ -1,1 +1,2 @@
 compiler.jvmci.events.JvmciShutdownEventListener
+compiler.jvmci.common.JVMCIHelpers
--- a/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Tue Oct 18 13:24:02 2016 +0200
+++ b/hotspot/test/compiler/jvmci/events/JvmciShutdownEventTest.java	Tue Oct 11 00:08:20 2016 +0200
@@ -34,9 +34,8 @@
  *
  * @build compiler.jvmci.common.JVMCIHelpers
  *        compiler.jvmci.events.JvmciShutdownEventListener
- * @run driver jdk.test.lib.FileInstaller ../common/services/ ./META-INF/services/
  * @run driver jdk.test.lib.FileInstaller ./JvmciShutdownEventTest.config
- *     ./META-INF/services/jdk.vm.ci.hotspot.services.HotSpotVMEventListener
+ *     ./META-INF/services/jdk.vm.ci.services.JVMCIServiceLocator
  * @run driver ClassFileInstaller
  *      compiler.jvmci.common.JVMCIHelpers$EmptyHotspotCompiler
  *      compiler.jvmci.common.JVMCIHelpers$EmptyCompilerFactory