# HG changeset patch # User Doug Simon # Date 1433882674 -7200 # Node ID 543f150e7fa04f5a4822789b33ae2b7bd27ddf4c # Parent b1234c06ea4985d000cd6df91cd20c5dd1ecac41 com.oracle.jvmci.service.Service is now a marker for service implementations available via JVMCI; removed Truffle -> JVMCI dependency diff -r b1234c06ea49 -r 543f150e7fa0 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java Tue Jun 09 22:31:05 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java Tue Jun 09 22:44:34 2015 +0200 @@ -26,7 +26,7 @@ import com.oracle.truffle.api.*; @ServiceProvider(TruffleRuntimeAccess.class) -public class HotSpotTruffleRuntimeAccess implements TruffleRuntimeAccess { +public class HotSpotTruffleRuntimeAccess implements TruffleRuntimeAccess, Service { public TruffleRuntime getRuntime() { return HotSpotTruffleRuntime.makeInstance(); } diff -r b1234c06ea49 -r 543f150e7fa0 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Tue Jun 09 22:31:05 2015 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/Truffle.java Tue Jun 09 22:44:34 2015 +0200 @@ -24,9 +24,9 @@ */ package com.oracle.truffle.api; +import java.lang.reflect.*; import java.security.*; -import com.oracle.jvmci.service.*; import com.oracle.truffle.api.impl.*; /** @@ -55,11 +55,22 @@ return AccessController.doPrivileged(new PrivilegedAction() { public TruffleRuntime run() { TruffleRuntimeAccess access = null; + Class servicesClass = null; try { - access = Services.loadSingle(TruffleRuntimeAccess.class, false); - } catch (NoClassDefFoundError e) { + servicesClass = Class.forName("com.oracle.jvmci.service.Services"); + } catch (ClassNotFoundException e) { // JVMCI is unavailable } + if (servicesClass != null) { + try { + Method m = servicesClass.getDeclaredMethod("loadSingle", Class.class, boolean.class); + access = (TruffleRuntimeAccess) m.invoke(null, TruffleRuntimeAccess.class, false); + } catch (Throwable e) { + // Fail fast for other errors + throw (InternalError) new InternalError().initCause(e); + } + } + // TODO: try standard ServiceLoader? if (access != null) { return access.getRuntime(); } diff -r b1234c06ea49 -r 543f150e7fa0 graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntimeAccess.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntimeAccess.java Tue Jun 09 22:31:05 2015 +0200 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/TruffleRuntimeAccess.java Tue Jun 09 22:44:34 2015 +0200 @@ -24,13 +24,10 @@ */ package com.oracle.truffle.api; -import com.oracle.jvmci.service.*; - /** - * A {@linkplain Service JVMCI service} that provides access to a {@link TruffleRuntime} - * implementation. + * A service that provides access to a {@link TruffleRuntime} implementation. */ -public interface TruffleRuntimeAccess extends Service { +public interface TruffleRuntimeAccess { /** * Gets the {@link TruffleRuntime} implementation available via this access object. diff -r b1234c06ea49 -r 543f150e7fa0 jvmci/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java --- a/jvmci/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java Tue Jun 09 22:31:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.service.processor/src/com/oracle/jvmci/service/processor/ServiceProviderProcessor.java Tue Jun 09 22:44:34 2015 +0200 @@ -46,13 +46,13 @@ } private boolean verifyAnnotation(TypeMirror serviceInterface, TypeElement serviceProvider) { - if (!processingEnv.getTypeUtils().isSubtype(serviceInterface, baseJVMCIServiceInterface.asType())) { - String msg = String.format("Service interface class %s doesn't extend JVMCI service interface %s", serviceInterface, baseJVMCIServiceInterface); + 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 doesn't implement service interface %s", serviceProvider.getSimpleName(), serviceInterface); + String msg = String.format("Service provider class %s must implement service interface %s", serviceProvider.getSimpleName(), serviceInterface); processingEnv.getMessager().printMessage(Kind.ERROR, msg, serviceProvider); return false; } diff -r b1234c06ea49 -r 543f150e7fa0 jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java --- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java Tue Jun 09 22:31:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Service.java Tue Jun 09 22:44:34 2015 +0200 @@ -22,15 +22,11 @@ */ package com.oracle.jvmci.service; -import java.util.*; - /** - * Denotes a JVMCI service that can be loaded by {@link Services#load(Class)} or - * {@link Services#loadSingle(Class, boolean)}. JVMCI services differ from - * {@linkplain ServiceLoader#load(Class) standard} services in that they may have implementations - * 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. + * Marker interface for a service implementation that can be loaded by {@link Services#load(Class)} + * or {@link Services#loadSingle(Class, boolean)}. These implementations 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. * * @see Services * @see ServiceProvider diff -r b1234c06ea49 -r 543f150e7fa0 jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java --- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java Tue Jun 09 22:31:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/ServiceProvider.java Tue Jun 09 22:44:34 2015 +0200 @@ -25,9 +25,8 @@ import java.lang.annotation.*; /** - * Annotates a class that implements a {@linkplain Service JVMCI service}. This annotation is used - * by the JVMCI build system to deploy the necessary files used to {@linkplain Services#load(Class) - * load} JVMCI services at runtime. + * Annotates a JVMCI implementation 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. */ @Retention(RetentionPolicy.CLASS) @Target(ElementType.TYPE) diff -r b1234c06ea49 -r 543f150e7fa0 jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java --- a/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java Tue Jun 09 22:31:05 2015 +0200 +++ b/jvmci/com.oracle.jvmci.service/src/com/oracle/jvmci/service/Services.java Tue Jun 09 22:44:34 2015 +0200 @@ -27,7 +27,7 @@ import sun.reflect.*; /** - * An mechanism for loading {@linkplain Service JVMCI services}. + * An mechanism for loading services that have a {@linkplain Service JVMCI implementation}. */ public class Services { @@ -39,9 +39,9 @@ */ private static final boolean SuppressNoClassDefFoundError = Boolean.getBoolean(SUPPRESS_PROPERTY_NAME); - private static final ClassValue> cache = new ClassValue>() { + private static final ClassValue> cache = new ClassValue>() { @Override - protected List computeValue(Class type) { + protected List computeValue(Class type) { try { return Arrays.asList(getServiceImpls(type)); } catch (NoClassDefFoundError e) { @@ -59,14 +59,14 @@ }; /** - * Gets an {@link Iterable} of the implementations available for a given JVMCI service. + * Gets an {@link Iterable} of the JVMCI implementations available for a given service. * * @throws SecurityException if a security manager is present and it denies * {@link RuntimePermission}("jvmciServices") */ @SuppressWarnings("unchecked") @CallerSensitive - public static Iterable load(Class service) { + public static Iterable load(Class service) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("jvmciServices")); @@ -79,8 +79,8 @@ } /** - * Gets the implementation for a given service for which at most one implementation must be - * available. + * Gets the JVMCI implementation for a given service for which at most one implementation must + * be available. * * @param service the service whose implementation is being requested * @param required specifies if an {@link InternalError} should be thrown if no implementation @@ -88,9 +88,9 @@ * @throws SecurityException if a security manager is present and it denies * {@link RuntimePermission}("jvmciServices") */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked"}) @CallerSensitive - public static S loadSingle(Class service, boolean required) { + public static S loadSingle(Class service, boolean required) { SecurityManager sm = System.getSecurityManager(); if (sm != null) { sm.checkPermission(new RuntimePermission("jvmciServices")); diff -r b1234c06ea49 -r 543f150e7fa0 mx/FilterTypes.java --- a/mx/FilterTypes.java Tue Jun 09 22:31:05 2015 +0200 +++ b/mx/FilterTypes.java Tue Jun 09 22:44:34 2015 +0200 @@ -23,41 +23,46 @@ public class FilterTypes { - /** - * Prints to {@link System#out} the values in {@code args[1 .. N]} that denote classes that are - * {@link Class#isAssignableFrom(Class) assignable} to the type denoted in {@code args[0]}. The - * values are separated by {@code "|"}. - */ public static void main(String... args) throws Exception { Class jvmciServiceInterface = Class.forName(args[0]); - boolean needSep = false; StringBuilder buf = new StringBuilder(); for (int i = 1; i < args.length; ++i) { - String serviceName = args[i]; - Class service = lookupService(serviceName); - if (service != null && jvmciServiceInterface.isAssignableFrom(service)) { + 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(' '); } - buf.append(serviceName); - needSep = true; + buf.append(serviceName).append('=').append(impls); } } System.out.print(buf); } - - private static Class lookupService(String serviceName) { - 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 sinc the expectation is that the jars will be - // updated later on. - return Class.forName(serviceName, 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; - } + + 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; + } } } diff -r b1234c06ea49 -r 543f150e7fa0 mx/mx_graal.py --- a/mx/mx_graal.py Tue Jun 09 22:31:05 2015 +0200 +++ b/mx/mx_graal.py Tue Jun 09 22:44:34 2015 +0200 @@ -550,18 +550,24 @@ shutil.move(tmp, dstLib) os.chmod(dstLib, permissions) -def _filterJVMCIServices(serviceImplNames, classpath): +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__)) - cmd = [mx.java().java, '-cp', mx._cygpathU2W(os.pathsep.join([binDir] + classpath)), 'FilterTypes', 'com.oracle.jvmci.service.Service'] + serviceImplNames - services = subprocess.check_output(cmd) - if len(services) == 0: - return [] - return services.split('|') + 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: @@ -602,9 +608,8 @@ with zf.open(member) as optionsFile, \ file(targetpath, "wb") as target: shutil.copyfileobj(optionsFile, target) - jvmciServices = _filterJVMCIServices(servicesMap.keys(), jdkJars) - for serviceName in jvmciServices: - serviceImpls = servicesMap[serviceName] + servicesMap = _filterJVMCIServices(servicesMap, jdkJars) + for serviceName, serviceImpls in servicesMap.iteritems(): fd, tmp = tempfile.mkstemp(prefix=serviceName) f = os.fdopen(fd, 'w+') for serviceImpl in serviceImpls: @@ -614,7 +619,6 @@ shutil.move(tmp, target) if mx.get_os() != 'windows': os.chmod(target, JDK_UNIX_PERMISSIONS_FILE) - return (jvmciServices, optionsFiles) def _updateJVMCIFiles(jdkDir): jreJVMCIDir = join(jdkDir, 'jre', 'lib', 'jvmci') diff -r b1234c06ea49 -r 543f150e7fa0 mx/suite.py --- a/mx/suite.py Tue Jun 09 22:31:05 2015 +0200 +++ b/mx/suite.py Tue Jun 09 22:44:34 2015 +0200 @@ -1071,7 +1071,6 @@ "com.oracle.truffle.api" : { "subDir" : "graal", "sourceDirs" : ["src"], - "dependencies" : ["com.oracle.jvmci.service"], "javaCompliance" : "1.7", "workingSets" : "API,Truffle", },