changeset 21937:3a292e8b9e51

replaced Service marker interface with non-standard META-INF directory names to differentiate JVMCI providers from standard service providers META-INF/services/ files for Options provider are now generated directly from files in META-INF/jvmci.options/
author Doug Simon <doug.simon@oracle.com>
date Fri, 12 Jun 2015 01:19:57 +0200
parents 11f241f26c61
children 95956bc1b1a3
files graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeAccess.java graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java jvmci/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/Compiler.java jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugConfigCustomizer.java jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugInitializationPropertyProvider.java jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/TTYStreamProvider.java jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIBackendFactory.java jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotVMEventListener.java jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/events/EventProvider.java jvmci/com.oracle.jvmci.options.processor/src/com/oracle/jvmci/options/processor/OptionProcessor.java jvmci/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java make/Makefile make/jvmci.make mx/FilterTypes.java mx/mx_graal.py mx/mx_graal_makefile.py mxtool/mx.py
diffstat 30 files changed, 160 insertions(+), 264 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeAccess.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.api.runtime/src/com/oracle/graal/api/runtime/GraalRuntimeAccess.java	Fri Jun 12 01:19:57 2015 +0200
@@ -22,13 +22,10 @@
  */
 package com.oracle.graal.api.runtime;
 
-import com.oracle.jvmci.service.*;
-
 /**
- * A {@linkplain Service JVMCI service} that provides access to a {@link GraalRuntime}
- * implementation.
+ * A service that provides access to a {@link GraalRuntime} implementation.
  */
-public interface GraalRuntimeAccess extends Service {
+public interface GraalRuntimeAccess {
 
     /**
      * Gets the {@link GraalRuntime} implementation available via this access object.
--- a/graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.code/src/com/oracle/graal/code/DisassemblerProvider.java	Fri Jun 12 01:19:57 2015 +0200
@@ -23,12 +23,11 @@
 package com.oracle.graal.code;
 
 import com.oracle.jvmci.code.*;
-import com.oracle.jvmci.service.*;
 
 /**
  * Interface providing capability for disassembling machine code.
  */
-public interface DisassemblerProvider extends Service {
+public interface DisassemblerProvider {
 
     /**
      * Gets a textual disassembly of a given compilation result.
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatementSet.java	Fri Jun 12 01:19:57 2015 +0200
@@ -25,9 +25,8 @@
 import java.util.*;
 
 import com.oracle.graal.compiler.gen.*;
-import com.oracle.jvmci.service.*;
 
-public interface MatchStatementSet extends Service {
+public interface MatchStatementSet {
     /**
      * @return the {@link NodeLIRBuilder} subclass which defined this set of {@link MatchStatement}
      *         instances.
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackendFactory.java	Fri Jun 12 01:19:57 2015 +0200
@@ -24,9 +24,8 @@
 
 import com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime.Options;
 import com.oracle.jvmci.runtime.*;
-import com.oracle.jvmci.service.*;
 
-public interface HotSpotBackendFactory extends Service {
+public interface HotSpotBackendFactory {
 
     HotSpotBackend createBackend(HotSpotGraalRuntimeProvider runtime, JVMCIBackend jvmciBackend, HotSpotBackend host);
 
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/ReplacementsProvider.java	Fri Jun 12 01:19:57 2015 +0200
@@ -25,12 +25,11 @@
 import com.oracle.graal.api.replacements.*;
 import com.oracle.jvmci.code.*;
 import com.oracle.jvmci.meta.*;
-import com.oracle.jvmci.service.*;
 
 /**
  * Interface for service providers that register replacements with the compiler.
  */
-public interface ReplacementsProvider extends Service {
+public interface ReplacementsProvider {
 
     void registerReplacements(MetaAccessProvider metaAccess, LoweringProvider lowerer, SnippetReflectionProvider snippetReflection, Replacements replacements, TargetDescription target);
 }
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/CompilerConfiguration.java	Fri Jun 12 01:19:57 2015 +0200
@@ -27,9 +27,8 @@
 import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase.PostAllocationOptimizationContext;
 import com.oracle.graal.lir.phases.PreAllocationOptimizationPhase.PreAllocationOptimizationContext;
 import com.oracle.graal.phases.*;
-import com.oracle.jvmci.service.*;
 
-public interface CompilerConfiguration extends Service {
+public interface CompilerConfiguration {
 
     PhaseSuite<HighTierContext> createHighTier();
 
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java	Fri Jun 12 01:19:57 2015 +0200
@@ -26,7 +26,7 @@
 import com.oracle.truffle.api.*;
 
 @ServiceProvider(TruffleRuntimeAccess.class)
-public class HotSpotTruffleRuntimeAccess implements TruffleRuntimeAccess, Service {
+public class HotSpotTruffleRuntimeAccess implements TruffleRuntimeAccess {
     public TruffleRuntime getRuntime() {
         return HotSpotTruffleRuntime.makeInstance();
     }
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/HotSpotNativeFunctionInterfaceAccess.java	Fri Jun 12 01:19:57 2015 +0200
@@ -27,7 +27,7 @@
 import com.oracle.nfi.api.*;
 
 @ServiceProvider(NativeFunctionInterfaceAccess.class)
-public class HotSpotNativeFunctionInterfaceAccess implements NativeFunctionInterfaceAccess, Service {
+public class HotSpotNativeFunctionInterfaceAccess implements NativeFunctionInterfaceAccess {
     private final NativeFunctionInterface instance = HotSpotTruffleRuntime.createNativeFunctionInterface();
 
     public NativeFunctionInterface getNativeFunctionInterface() {
--- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/RawNativeCallNodeFactory.java	Fri Jun 12 01:19:57 2015 +0200
@@ -25,12 +25,11 @@
 import com.oracle.jvmci.meta.Kind;
 import com.oracle.jvmci.meta.JavaConstant;
 import com.oracle.graal.nodes.*;
-import com.oracle.jvmci.service.*;
 
 /**
  * Factory for creating a node that makes a direct call to a native function pointer.
  */
-public interface RawNativeCallNodeFactory extends Service {
+public interface RawNativeCallNodeFactory {
     FixedWithNextNode createRawCallNode(Kind returnType, JavaConstant functionPointer, ValueNode... args);
 
     String getArchitecture();
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/GraalTruffleRuntime.java	Fri Jun 12 01:19:57 2015 +0200
@@ -38,8 +38,12 @@
 import com.oracle.graal.nodes.*;
 import com.oracle.graal.truffle.debug.*;
 import com.oracle.graal.truffle.unsafe.*;
+import com.oracle.jvmci.code.*;
+import com.oracle.jvmci.code.stack.*;
 import com.oracle.jvmci.debug.*;
 import com.oracle.jvmci.debug.Debug.Scope;
+import com.oracle.jvmci.meta.*;
+import com.oracle.jvmci.service.*;
 import com.oracle.truffle.api.*;
 import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
 import com.oracle.truffle.api.frame.*;
@@ -69,9 +73,9 @@
     }
 
     private static <T extends PrioritizedServiceProvider> T loadPrioritizedServiceProvider(Class<T> clazz) {
-        ServiceLoader<T> serviceLoader = ServiceLoader.load(clazz, GraalTruffleRuntime.class.getClassLoader());
+        Iterable<T> providers = Services.load(clazz);
         T bestFactory = null;
-        for (T factory : serviceLoader) {
+        for (T factory : providers) {
             if (bestFactory == null) {
                 bestFactory = factory;
             } else if (factory.getPriority() > bestFactory.getPriority()) {
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/LoopNodeFactory.java	Fri Jun 12 01:19:57 2015 +0200
@@ -22,10 +22,9 @@
  */
 package com.oracle.graal.truffle;
 
-import com.oracle.jvmci.service.*;
 import com.oracle.truffle.api.nodes.*;
 
-public interface LoopNodeFactory extends PrioritizedServiceProvider, Service {
+public interface LoopNodeFactory extends PrioritizedServiceProvider {
 
     LoopNode create(RepeatingNode repeatingNode);
 
--- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/OptimizedCallTargetInstrumentationFactory.java	Fri Jun 12 01:19:57 2015 +0200
@@ -24,13 +24,12 @@
 
 import com.oracle.jvmci.meta.ResolvedJavaMethod;
 import com.oracle.graal.lir.asm.*;
-import com.oracle.jvmci.service.*;
 
 /**
  * A service for creating a specialized {@link CompilationResultBuilder} used to inject code into
  * {@link OptimizedCallTarget#call(Object[])}.
  */
-public interface OptimizedCallTargetInstrumentationFactory extends CompilationResultBuilderFactory, Service {
+public interface OptimizedCallTargetInstrumentationFactory extends CompilationResultBuilderFactory {
 
     /**
      * Gets the architecture supported by this factory.
--- a/jvmci/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/Compiler.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/Compiler.java	Fri Jun 12 01:19:57 2015 +0200
@@ -25,9 +25,8 @@
 import com.oracle.jvmci.code.*;
 import com.oracle.jvmci.meta.*;
 import com.oracle.jvmci.options.*;
-import com.oracle.jvmci.service.*;
 
-public interface Compiler extends Service {
+public interface Compiler {
     int INVOCATION_ENTRY_BCI = -1;
 
     @Option(help = "", type = OptionType.Debug) OptionValue<String> PrintFilter = new OptionValue<>(null);
--- a/jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugConfigCustomizer.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugConfigCustomizer.java	Fri Jun 12 01:19:57 2015 +0200
@@ -22,8 +22,6 @@
  */
 package com.oracle.jvmci.debug;
 
-import com.oracle.jvmci.service.*;
-
-public interface DebugConfigCustomizer extends Service {
+public interface DebugConfigCustomizer {
     void customize(DebugConfig config);
 }
--- a/jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugInitializationPropertyProvider.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugInitializationPropertyProvider.java	Fri Jun 12 01:19:57 2015 +0200
@@ -22,11 +22,9 @@
  */
 package com.oracle.jvmci.debug;
 
-import com.oracle.jvmci.service.*;
-
 /**
  * Sets one or more system properties used during initialization of the {@link Debug} class.
  */
-public interface DebugInitializationPropertyProvider extends Service {
+public interface DebugInitializationPropertyProvider {
     void apply();
 }
--- a/jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/TTYStreamProvider.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/TTYStreamProvider.java	Fri Jun 12 01:19:57 2015 +0200
@@ -24,11 +24,9 @@
 
 import java.io.*;
 
-import com.oracle.jvmci.service.*;
-
 /**
  * Provides a {@link PrintStream} that writes to the underlying log stream of the VM.
  */
-public interface TTYStreamProvider extends Service {
+public interface TTYStreamProvider {
     PrintStream getStream();
 }
--- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIBackendFactory.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIBackendFactory.java	Fri Jun 12 01:19:57 2015 +0200
@@ -23,9 +23,8 @@
 package com.oracle.jvmci.hotspot;
 
 import com.oracle.jvmci.runtime.*;
-import com.oracle.jvmci.service.*;
 
-public interface HotSpotJVMCIBackendFactory extends Service {
+public interface HotSpotJVMCIBackendFactory {
 
     JVMCIBackend createJVMCIBackend(HotSpotJVMCIRuntimeProvider runtime, JVMCIBackend host);
 
--- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotVMEventListener.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotVMEventListener.java	Fri Jun 12 01:19:57 2015 +0200
@@ -22,9 +22,7 @@
  */
 package com.oracle.jvmci.hotspot;
 
-import com.oracle.jvmci.service.*;
-
-public interface HotSpotVMEventListener extends Service {
+public interface HotSpotVMEventListener {
 
     /**
      * Notifies this client that HotSpot is running in CompileTheWorld mode and the JVMCI compiler
--- a/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/events/EventProvider.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/events/EventProvider.java	Fri Jun 12 01:19:57 2015 +0200
@@ -22,12 +22,10 @@
  */
 package com.oracle.jvmci.hotspot.events;
 
-import com.oracle.jvmci.service.*;
-
 /**
  * A provider that provides a specific implementation for events that can be logged in the compiler.
  */
-public interface EventProvider extends Service {
+public interface EventProvider {
 
     /**
      * An instant event is an event that is not considered to have taken any time.
--- a/jvmci/com.oracle.jvmci.options.processor/src/com/oracle/jvmci/options/processor/OptionProcessor.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.options.processor/src/com/oracle/jvmci/options/processor/OptionProcessor.java	Fri Jun 12 01:19:57 2015 +0200
@@ -37,8 +37,11 @@
 
 /**
  * Processes static fields annotated with {@link Option}. An {@link Options} service is generated
- * for each top level class containing at least one such field. These service objects can be
- * retrieved as follows:
+ * for each top level class containing at least one such field. The name of the generated class for
+ * top level class {@code com.foo.Bar} is {@code com.foo.Bar_Options}.
+ *
+ * The build system is expected to create the appropriate entries in {@code META-INF/services/} such
+ * that these service objects can be retrieved as follows:
  *
  * <pre>
  * ServiceLoader&lt;Options&gt; sl = ServiceLoader.load(Options.class);
@@ -210,23 +213,14 @@
         }
 
         try {
-            createProviderFile(pkg, optionsClassName, originatingElements);
             createOptionsFile(info, pkg, topDeclaringClass.toString(), originatingElements);
         } catch (IOException e) {
             processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage(), info.topDeclaringType);
         }
     }
 
-    private void createProviderFile(String pkg, String providerClassName, Element... originatingElements) throws IOException {
-        String filename = "META-INF/providers/" + pkg + "." + providerClassName;
-        FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements);
-        PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
-        writer.println(Options.class.getName());
-        writer.close();
-    }
-
     private void createOptionsFile(OptionsInfo info, String pkg, String relativeName, Element... originatingElements) throws IOException {
-        String filename = "META-INF/options/" + pkg + "." + relativeName;
+        String filename = "META-INF/jvmci.options/" + pkg + "." + relativeName;
         FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, originatingElements);
         PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
         Types types = processingEnv.getTypeUtils();
@@ -267,7 +261,7 @@
             case "String":
                 return 's';
             default:
-                processingEnv.getMessager().printMessage(Kind.ERROR, "Unsoported option type: " + option.type, option.field);
+                processingEnv.getMessager().printMessage(Kind.ERROR, "Unsupported option type: " + option.type, option.field);
                 throw new IllegalArgumentException();
         }
     }
--- a/jvmci/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java	Fri Jun 12 01:19:57 2015 +0200
@@ -38,7 +38,6 @@
 public class ServiceProviderProcessor extends AbstractProcessor {
 
     private final Set<TypeElement> processed = new HashSet<>();
-    private TypeElement baseJVMCIServiceInterface;
 
     @Override
     public SourceVersion getSupportedSourceVersion() {
@@ -46,11 +45,6 @@
     }
 
     private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) {
-        if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), baseJVMCIServiceInterface.asType())) {
-            String msg = String.format("Service implementation class %s must implement %s", serviceProvider.getSimpleName(), baseJVMCIServiceInterface);
-            processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
-            return false;
-        }
         if (!processingEnv.getTypeUtils().isSubtype(serviceProvider.asType(), serviceInterface)) {
             String msg = String.format("Service provider class %s must implement service interface %s", serviceProvider.getSimpleName(), serviceInterface);
             processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider);
@@ -90,7 +84,7 @@
             return;
         }
 
-        String filename = "META-INF/providers/" + serviceProvider.getQualifiedName();
+        String filename = "META-INF/jvmci.providers/" + serviceProvider.getQualifiedName();
         try {
             FileObject file = processingEnv.getFiler().createResource(StandardLocation.CLASS_OUTPUT, "", filename, serviceProvider);
             PrintWriter writer = new PrintWriter(new OutputStreamWriter(file.openOutputStream(), "UTF-8"));
@@ -107,8 +101,6 @@
             return true;
         }
 
-        baseJVMCIServiceInterface = processingEnv.getElementUtils().getTypeElement("com.oracle.jvmci.service.Service");
-
         for (Element element : roundEnv.getElementsAnnotatedWith(ServiceProvider.class)) {
             assert element.getKind().isClass();
             processElement((TypeElement) element);
--- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java	Fri Jun 12 01:06:36 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2013, 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.jvmci.service;
-
-/**
- * Marker interface for a service provider that can be loaded by {@link Services#load(Class)} or
- * {@link Services#loadSingle(Class, boolean)}. These providers are hidden behind a class loader not
- * accessible to applications. For this reason, {@link Services#load(Class)} and
- * {@link Services#loadSingle(Class, boolean)} perform {@link SecurityManager} checks.
- *
- * If this marker interface is applied to a service interface <i>S</I> as opposed to a service
- * provider, then all providers implementing <i>S</i> have the semantics described above.
- *
- * @see Services
- * @see ServiceProvider
- */
-public interface Service {
-}
--- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java	Fri Jun 12 01:19:57 2015 +0200
@@ -25,8 +25,8 @@
 import java.lang.annotation.*;
 
 /**
- * Annotates a JVMCI provider of a service. This annotation is used by the JVMCI build system to
- * deploy the necessary files used to {@linkplain Services#load(Class) load} services at runtime.
+ * Annotates a service provider than can be loaded via {@linkplain Services#load(Class)} or
+ * {@link Services#loadSingle(Class, boolean)}.
  */
 @Retention(RetentionPolicy.CLASS)
 @Target(ElementType.TYPE)
--- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java	Fri Jun 12 01:06:36 2015 +0200
+++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java	Fri Jun 12 01:19:57 2015 +0200
@@ -27,7 +27,9 @@
 import sun.reflect.*;
 
 /**
- * An mechanism for accessing {@link Service JVMCI service providers}.
+ * An mechanism for accessing service providers via JVMCI. These providers are loaded via a JVMCI
+ * class loader that is hidden from application code. Hence the {@link SecurityManager} checks in
+ * {@link #load(Class)} and {@link #loadSingle(Class, boolean)}.
  */
 public class Services {
 
--- a/make/Makefile	Fri Jun 12 01:06:36 2015 +0200
+++ b/make/Makefile	Fri Jun 12 01:19:57 2015 +0200
@@ -630,10 +630,10 @@
 $(EXPORT_JRE_LIB_JVMCI_DIR)/%.jar: $(SHARED_DIR)/%.jar
 	$(install-file)
 
-$(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/%: $(SHARED_DIR)/services/%
+$(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/%: $(SHARED_DIR)/jvmci.services/%
 	$(install-file)
 
-$(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/%: $(SHARED_DIR)/options/%
+$(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/%: $(SHARED_DIR)/jvmci.options/%
 	$(install-file)
 
 $(EXPORT_INCLUDE_DIR)/%: $(HS_SRC_DIR)/share/vm/code/%
--- a/make/jvmci.make	Fri Jun 12 01:06:36 2015 +0200
+++ b/make/jvmci.make	Fri Jun 12 01:19:57 2015 +0200
@@ -8,13 +8,12 @@
 JAVAC=$(ABS_BOOTDIR)/bin/javac -g -target 1.8
 JAR=$(ABS_BOOTDIR)/bin/jar
 
-EXPORTED_FILES_ADDITIONAL=$(TARGET)/options $(TARGET)/services
 HS_COMMON_SRC=.
 
 # Directories, where the generated property-files reside within the JAR files
-PROVIDERS_INF=/META-INF/providers
-SERVICES_INF=/META-INF/services
-OPTIONS_INF=/META-INF/options
+PROVIDERS_INF=/META-INF/jvmci.providers
+SERVICES_INF=/META-INF/jvmci.services
+OPTIONS_INF=/META-INF/jvmci.options
 
 ifeq ($(ABS_BOOTDIR),)
     $(error Variable ABS_BOOTDIR must be set to a JDK installation.)
@@ -27,13 +26,13 @@
 space :=
 space +=
 
-# Takes the option files of the options annotation processor and merges them into a single file
+# Takes the provider files created by ServiceProviderProcessor (the processor
+# for the @ServiceProvider annotation) and merges them into a single file.
 # Arguments:
 #  1: directory with contents of the JAR file
-define process_options
+define process_providers
     $(eval providers=$(1)/$(PROVIDERS_INF))
     $(eval services=$(1)/$(SERVICES_INF))
-    $(eval options=$(1)/$(OPTIONS_INF))
     $(QUIETLY) test -d $(services) || mkdir -p $(services)
     $(QUIETLY) test ! -d $(providers) || (cd $(providers) && for i in $$(ls); do c=$$(cat $$i); echo $$i >> $(abspath $(services))/$$c; rm $$i; done)
 
@@ -44,20 +43,33 @@
     $(QUIETLY) test ! -f $(vmconfig) || (mkdir -p $(vmconfigDest) && cp $(vmconfig) $(vmconfigDest))
 endef
 
-# Extracts META-INF/services and META-INF/options of a JAR file into a given directory
+# Reads the files in jvmci.options/ created by OptionProcessor (the processor for the @Option annotation)
+# and appends to services/com.oracle.jvmci.options.Options entries for the providers
+# also created by the same processor.
+# Arguments:
+#  1: directory with contents of the JAR file
+define process_options
+    $(eval options=$(1)/$(OPTIONS_INF))
+    $(eval services=$(1)/META-INF/services)
+    $(QUIETLY) test -d $(services) || mkdir -p $(services)
+    $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_Options >> $(abspath $(services))/com.oracle.jvmci.options.Options; done)
+endef
+
+# Extracts META-INF/jvmci.services and META-INF/jvmci.options of a JAR file into a given directory
 # Arguments:
 #  1: JAR file to extract
 #  2: target directory
 define extract
     $(eval TMP := $(shell mktemp -d $(TARGET)/tmp_XXXXX))
-    $(QUIETLY) mkdir -p $(2);
+    $(QUIETLY) mkdir -p $(2)
     $(QUIETLY) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \
-        ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) &&  (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2))));
-    $(QUIETLY) rm -r $(TMP);
-    $(QUIETLY) cp $(1) $(2);
+        ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && \
+         (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2))))
+    $(QUIETLY) rm -r $(TMP)
+    $(QUIETLY) cp $(1) $(2)
 endef
 
-# Calls $(JAVAC) with the bootclasspath $(JDK_BOOTCLASSPATH); sources are taken from the automatic variable $^
+# Calls $(JAVAC) with the boot class path $(JDK_BOOTCLASSPATH) and sources taken from the automatic variable $^
 # Arguments:
 #  1: processorpath
 #  2: classpath
@@ -66,17 +78,22 @@
 define build_and_jar
     $(info Building $(4))
     $(eval TMP := $(shell mkdir -p $(TARGET) && mktemp -d $(TARGET)/tmp_XXXXX))
-    $(QUIETLY) $(JAVAC) -d $(TMP) -processorpath :$(1) -bootclasspath $(JDK_BOOTCLASSPATH) -cp :$(2) $(filter %.java,$^);
-    $(QUIETLY) test "$(3)" = "" || cp -r $(3) $(TMP);
-    $(QUIETLY) $(call process_options,$(TMP));
+    $(QUIETLY) $(JAVAC) -d $(TMP) -processorpath :$(1) -bootclasspath $(JDK_BOOTCLASSPATH) -cp :$(2) $(filter %.java,$^)
+    $(QUIETLY) test "$(3)" = "" || cp -r $(3) $(TMP)
+    $(QUIETLY) $(call process_options,$(TMP))
+    $(QUIETLY) $(call process_providers,$(TMP))
     $(QUIETLY) mkdir -p $(shell dirname $(4))
     $(QUIETLY) $(JAR) cf $(4) -C $(TMP) .
-    $(QUIETLY) rm -r $(TMP);
+    $(QUIETLY) rm -r $(TMP)
 endef
 
-# Verifies if the defs.make contain the exported files of services/
-define verify_export_def_make
-    $(foreach file,$(1),$(if $(shell grep '$(2)$(file)' $(3) > /dev/null && echo found), , $(error "Pattern '$(2)$(file)' not found in $(3)")))
+# Verifies that make/defs.make contains a line for each file in a list of files.
+# Arguments:
+#  1: list of files
+#  2: prefix to apply to each file to create match pattern
+define verify_defs_make
+    $(eval defs=make/defs.make)
+    $(foreach file,$(1),$(if $(shell grep '$(2)$(file)' $(defs) > /dev/null && echo found), , $(error "Pattern '$(2)$(file)' not found in $(defs)")))
 endef
 
 all: default
@@ -85,8 +102,8 @@
 	$(info Put $(EXPORTED_FILES) into SHARED_DIR $(SHARED_DIR))
 	$(QUIETLY) mkdir -p $(SHARED_DIR)
 	$(foreach export,$(EXPORTED_FILES),$(call extract,$(export),$(SHARED_DIR)))
-	$(call verify_export_def_make,$(notdir $(wildcard $(SHARED_DIR)/services/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/,make/defs.make)
-	$(call verify_export_def_make,$(notdir $(wildcard $(SHARED_DIR)/options/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/,make/defs.make)
+	$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.services/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/)
+	$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.options/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/)
 .PHONY: export
 
 
--- a/mx/FilterTypes.java	Fri Jun 12 01:06:36 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +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.
- */
-
-public class FilterTypes {
-
-    public static void main(String... args) throws Exception {
-        Class<?> jvmciServiceInterface = Class.forName(args[0]);
-        StringBuilder buf = new StringBuilder();
-        for (int i = 1; i < args.length; ++i) {
-            String[] e = args[i].split("=");
-            String serviceName = e[0];
-            String implNames = e[1];
-
-            StringBuilder impls = new StringBuilder();
-            for (String implName : implNames.split(",")) {
-                Class<?> impl = lookup(implName);
-                if (impl != null && jvmciServiceInterface.isAssignableFrom(impl)) {
-                    if (impls.length() != 0) {
-                        impls.append(',');
-                    }
-                    impls.append(implName);
-                }
-            }
-            if (impls.length() != 0) {
-                if (buf.length() != 0) {
-                    buf.append(' ');
-                }
-                buf.append(serviceName).append('=').append(impls);
-            }
-        }
-        System.out.print(buf);
-    }
-
-    private static Class<?> lookup(String name) {
-        try {
-            // This can fail in the case of running against a JDK
-            // with out of date JVMCI jars. In that case, just print
-            // a warning since the expectation is that the jars will be
-            // updated later on.
-            return Class.forName(name, false, FilterTypes.class.getClassLoader());
-        } catch (ClassNotFoundException e) {
-            // Must be stderr to avoid polluting the result being
-            // written to stdout.
-            System.err.println(e);
-            return null;
-        }
-    }
-}
--- a/mx/mx_graal.py	Fri Jun 12 01:06:36 2015 +0200
+++ b/mx/mx_graal.py	Fri Jun 12 01:19:57 2015 +0200
@@ -550,71 +550,50 @@
         shutil.move(tmp, dstLib)
         os.chmod(dstLib, permissions)
 
-def _filterJVMCIServices(servicesMap, 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__))
-    serialized = [k + '=' + ','.join(v) for k, v in servicesMap.iteritems()]
-    cmd = [mx.java().java, '-cp', mx._cygpathU2W(os.pathsep.join([binDir] + classpath)), 'FilterTypes', 'com.oracle.jvmci.service.Service'] + serialized
-    serialized = subprocess.check_output(cmd)
-    if len(serialized) == 0:
-        return {}
-    servicesMap = {}
-    for e in serialized.split(' '):
-        k, v = e.split('=')
-        impls = v.split(',')
-        servicesMap[k] = impls
-    return servicesMap
-
-def _extractJVMCIFiles(jdkJars, jvmciJars, servicesDir, optionsDir, cleanDestination=True):
-    if cleanDestination:
-        if exists(servicesDir):
-            shutil.rmtree(servicesDir)
-        if exists(optionsDir):
-            shutil.rmtree(optionsDir)
+def _extractJVMCIFiles(jdkJars, jvmciJars, servicesDir, optionsDir):
+    if exists(servicesDir):
+        shutil.rmtree(servicesDir)
+    if exists(optionsDir):
+        shutil.rmtree(optionsDir)
     if not exists(servicesDir):
         os.makedirs(servicesDir)
     if not exists(optionsDir):
         os.makedirs(optionsDir)
-    servicesMap = {}
+    jvmciServices = {}
     optionsFiles = []
     for jar in jvmciJars:
         if os.path.isfile(jar):
             with zipfile.ZipFile(jar) as zf:
                 for member in zf.namelist():
-                    if member.startswith('META-INF/services') and member:
-                        serviceName = basename(member)
-                        if serviceName == "":
+                    if member.startswith('META-INF/jvmci.services') and member:
+                        service = basename(member)
+                        if service == "":
                             continue # Zip files may contain empty entries for directories (jar -cf ... creates such)
                         # we don't handle directories
-                        assert serviceName and member == 'META-INF/services/' + serviceName
+                        assert service and member == 'META-INF/jvmci.services/' + service
                         with zf.open(member) as serviceFile:
-                            serviceImpls = servicesMap.setdefault(serviceName, [])
+                            providers = jvmciServices.setdefault(service, [])
                             for line in serviceFile.readlines():
                                 line = line.strip()
                                 if line:
-                                    serviceImpls.append(line)
-                    elif member.startswith('META-INF/options'):
+                                    providers.append(line)
+                    elif member.startswith('META-INF/jvmci.options'):
                         filename = basename(member)
                         if filename == "":
                             continue # Zip files may contain empty entries for directories (jar -cf ... creates such)
                         # we don't handle directories
-                        assert filename and member == 'META-INF/options/' + filename
+                        assert filename and member == 'META-INF/jvmci.options/' + filename
                         targetpath = join(optionsDir, filename)
                         optionsFiles.append(filename)
                         with zf.open(member) as optionsFile, \
                              file(targetpath, "wb") as target:
                             shutil.copyfileobj(optionsFile, target)
-    servicesMap = _filterJVMCIServices(servicesMap, jdkJars)
-    for serviceName, serviceImpls in servicesMap.iteritems():
-        fd, tmp = tempfile.mkstemp(prefix=serviceName)
+    for service, providers in jvmciServices.iteritems():
+        fd, tmp = tempfile.mkstemp(prefix=service)
         f = os.fdopen(fd, 'w+')
-        for serviceImpl in serviceImpls:
-            f.write(serviceImpl + os.linesep)
-        target = join(servicesDir, serviceName)
+        for provider in providers:
+            f.write(provider + os.linesep)
+        target = join(servicesDir, service)
         f.close()
         shutil.move(tmp, target)
         if mx.get_os() != 'windows':
--- a/mx/mx_graal_makefile.py	Fri Jun 12 01:06:36 2015 +0200
+++ b/mx/mx_graal_makefile.py	Fri Jun 12 01:19:57 2015 +0200
@@ -171,9 +171,9 @@
 HS_COMMON_SRC=.
 
 # Directories, where the generated property-files reside within the JAR files
-PROVIDERS_INF=/META-INF/providers
-SERVICES_INF=/META-INF/services
-OPTIONS_INF=/META-INF/options
+PROVIDERS_INF=/META-INF/jvmci.providers
+SERVICES_INF=/META-INF/jvmci.services
+OPTIONS_INF=/META-INF/jvmci.options
 
 ifeq ($(ABS_BOOTDIR),)
     $(error Variable ABS_BOOTDIR must be set to a JDK installation.)
@@ -186,13 +186,13 @@
 space :=
 space +=
 
-# Takes the option files of the options annotation processor and merges them into a single file
+# Takes the provider files created by ServiceProviderProcessor (the processor
+# for the @ServiceProvider annotation) and merges them into a single file.
 # Arguments:
 #  1: directory with contents of the JAR file
-define process_options
+define process_providers
     $(eval providers=$(1)/$(PROVIDERS_INF))
     $(eval services=$(1)/$(SERVICES_INF))
-    $(eval options=$(1)/$(OPTIONS_INF))
     $(QUIETLY) test -d $(services) || mkdir -p $(services)
     $(QUIETLY) test ! -d $(providers) || (cd $(providers) && for i in $$(ls); do c=$$(cat $$i); echo $$i >> $(abspath $(services))/$$c; rm $$i; done)
 
@@ -203,20 +203,33 @@
     $(QUIETLY) test ! -f $(vmconfig) || (mkdir -p $(vmconfigDest) && cp $(vmconfig) $(vmconfigDest))
 endef
 
-# Extracts META-INF/services and META-INF/options of a JAR file into a given directory
+# Reads the files in jvmci.options/ created by OptionProcessor (the processor for the @Option annotation)
+# and appends to services/com.oracle.jvmci.options.Options entries for the providers
+# also created by the same processor.
+# Arguments:
+#  1: directory with contents of the JAR file
+define process_options
+    $(eval options=$(1)/$(OPTIONS_INF))
+    $(eval services=$(1)/META-INF/services)
+    $(QUIETLY) test -d $(services) || mkdir -p $(services)
+    $(QUIETLY) test ! -d $(options) || (cd $(options) && for i in $$(ls); do echo $${i}_Options >> $(abspath $(services))/com.oracle.jvmci.options.Options; done)
+endef
+
+# Extracts META-INF/jvmci.services and META-INF/jvmci.options of a JAR file into a given directory
 # Arguments:
 #  1: JAR file to extract
 #  2: target directory
 define extract
     $(eval TMP := $(shell mktemp -d $(TARGET)/tmp_XXXXX))
-    $(QUIETLY) mkdir -p $(2);
+    $(QUIETLY) mkdir -p $(2)
     $(QUIETLY) cd $(TMP) && $(JAR) xf $(abspath $(1)) && \\
-        ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) &&  (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2))));
-    $(QUIETLY) rm -r $(TMP);
-    $(QUIETLY) cp $(1) $(2);
+        ((test ! -d .$(SERVICES_INF) || cp -r .$(SERVICES_INF) $(abspath $(2))) && \\
+         (test ! -d .$(OPTIONS_INF) || cp -r .$(OPTIONS_INF) $(abspath $(2))))
+    $(QUIETLY) rm -r $(TMP)
+    $(QUIETLY) cp $(1) $(2)
 endef
 
-# Calls $(JAVAC) with the bootclasspath $(JDK_BOOTCLASSPATH); sources are taken from the automatic variable $^
+# Calls $(JAVAC) with the boot class path $(JDK_BOOTCLASSPATH) and sources taken from the automatic variable $^
 # Arguments:
 #  1: processorpath
 #  2: classpath
@@ -225,17 +238,22 @@
 define build_and_jar
     $(info Building $(4))
     $(eval TMP := $(shell mkdir -p $(TARGET) && mktemp -d $(TARGET)/tmp_XXXXX))
-    $(QUIETLY) $(JAVAC) -d $(TMP) -processorpath :$(1) -bootclasspath $(JDK_BOOTCLASSPATH) -cp :$(2) $(filter %.java,$^);
-    $(QUIETLY) test "$(3)" = "" || cp -r $(3) $(TMP);
-    $(QUIETLY) $(call process_options,$(TMP));
+    $(QUIETLY) $(JAVAC) -d $(TMP) -processorpath :$(1) -bootclasspath $(JDK_BOOTCLASSPATH) -cp :$(2) $(filter %.java,$^)
+    $(QUIETLY) test "$(3)" = "" || cp -r $(3) $(TMP)
+    $(QUIETLY) $(call process_options,$(TMP))
+    $(QUIETLY) $(call process_providers,$(TMP))
     $(QUIETLY) mkdir -p $(shell dirname $(4))
     $(QUIETLY) $(JAR) cf $(4) -C $(TMP) .
-    $(QUIETLY) rm -r $(TMP);
+    $(QUIETLY) rm -r $(TMP)
 endef
 
-# Verifies if the defs.make contain the exported files of services/
-define verify_export_def_make
-    $(foreach file,$(1),$(if $(shell grep '$(2)$(file)' $(3) > /dev/null && echo found), , $(error "Pattern '$(2)$(file)' not found in $(3)")))
+# Verifies that make/defs.make contains a line for each file in a list of files.
+# Arguments:
+#  1: list of files
+#  2: prefix to apply to each file to create match pattern
+define verify_defs_make
+    $(eval defs=make/defs.make)
+    $(foreach file,$(1),$(if $(shell grep '$(2)$(file)' $(defs) > /dev/null && echo found), , $(error "Pattern '$(2)$(file)' not found in $(defs)")))
 endef
 
 all: default
@@ -244,8 +262,8 @@
 \t$(info Put $(EXPORTED_FILES) into SHARED_DIR $(SHARED_DIR))
 \t$(QUIETLY) mkdir -p $(SHARED_DIR)
 \t$(foreach export,$(EXPORTED_FILES),$(call extract,$(export),$(SHARED_DIR)))
-\t$(call verify_export_def_make,$(notdir $(wildcard $(SHARED_DIR)/services/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/,make/defs.make)
-\t$(call verify_export_def_make,$(notdir $(wildcard $(SHARED_DIR)/options/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/,make/defs.make)
+\t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.services/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/)
+\t$(call verify_defs_make,$(notdir $(wildcard $(SHARED_DIR)/jvmci.options/*)),EXPORT_LIST += $$(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/)
 .PHONY: export
 
 """)
--- a/mxtool/mx.py	Fri Jun 12 01:06:36 2015 +0200
+++ b/mxtool/mx.py	Fri Jun 12 01:19:57 2015 +0200
@@ -181,6 +181,7 @@
             with Archiver(None if unified else self.sourcesPath) as srcArcRaw:
                 srcArc = arc if unified else srcArcRaw
                 services = {}
+                jvmciServices = {}
                 def overwriteCheck(zf, arcname, source):
                     if os.path.basename(arcname).startswith('.'):
                         logv('Excluding dotfile: ' + source)
@@ -220,12 +221,15 @@
                         libSourcePath = l.get_source_path(resolve=True)
                         if lpath:
                             with zipfile.ZipFile(lpath, 'r') as lp:
-                                for arcname in lp.namelist():
+                                entries = lp.namelist()
+                                for arcname in entries:
                                     if arcname.startswith('META-INF/services/') and not arcname == 'META-INF/services/':
                                         service = arcname[len('META-INF/services/'):]
                                         assert '/' not in service
                                         services.setdefault(service, []).extend(lp.read(arcname).splitlines())
                                     else:
+                                        assert not arcname.startswith('META-INF/jvmci.services/'), 'did not expect to see jvmci.services in ' + lpath
+                                        assert not arcname.startswith('META-INF/jvmci.options/'), 'did not expect to see jvmci.options in ' + lpath
                                         if not overwriteCheck(arc.zf, arcname, lpath + '!' + arcname):
                                             arc.zf.writestr(arcname, lp.read(arcname))
                         if srcArc.zf and libSourcePath:
@@ -248,12 +252,25 @@
                                 for service in files:
                                     with open(join(root, service), 'r') as fp:
                                         services.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
-                            elif relpath == join('META-INF', 'providers'):
+                            elif relpath == join('META-INF', 'jvmci.services'):
+                                for service in files:
+                                    with open(join(root, service), 'r') as fp:
+                                        jvmciServices.setdefault(service, []).extend([provider.strip() for provider in fp.readlines()])
+                            elif relpath == join('META-INF', 'jvmci.providers'):
                                 for provider in files:
                                     with open(join(root, provider), 'r') as fp:
                                         for service in fp:
-                                            services.setdefault(service.strip(), []).append(provider)
+                                            jvmciServices.setdefault(service.strip(), []).append(provider)
                             else:
+                                if relpath == join('META-INF', 'jvmci.options'):
+                                    # Need to create service files for the providers of the
+                                    # com.oracle.jvmci.options.Options service created by
+                                    # com.oracle.jvmci.options.processor.OptionProcessor.
+                                    for optionsOwner in files:
+                                        provider = optionsOwner + '_Options'
+                                        providerClassfile = join(outputDir, provider.replace('.', os.sep) + '.class')
+                                        assert exists(providerClassfile), 'missing generated Options provider ' + providerClassfile
+                                        services.setdefault('com.oracle.jvmci.options.Options', []).append(provider)
                                 for f in files:
                                     arcname = join(relpath, f).replace(os.sep, '/')
                                     if not overwriteCheck(arc.zf, arcname, join(root, f)):
@@ -274,10 +291,12 @@
                 for service, providers in services.iteritems():
                     arcname = 'META-INF/services/' + service
                     arc.zf.writestr(arcname, '\n'.join(providers))
+                for service, providers in jvmciServices.iteritems():
+                    arcname = 'META-INF/jvmci.services/' + service
+                    arc.zf.writestr(arcname, '\n'.join(providers))
 
         self.notify_updated()
 
-
     def notify_updated(self):
         for l in self.update_listeners:
             l(self)