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