1 /* 2 * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package jdk.vm.ci.hotspot; 24 25 import java.util.List; 26 import java.util.Set; 27 28 import jdk.vm.ci.code.CompilationRequest; 29 import jdk.vm.ci.common.JVMCIError; 30 import jdk.vm.ci.common.NativeImageReinitialize; 31 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime.Option; 32 import jdk.vm.ci.runtime.JVMCICompiler; 33 import jdk.vm.ci.runtime.JVMCICompilerFactory; 34 import jdk.vm.ci.runtime.JVMCIRuntime; 35 import jdk.vm.ci.services.JVMCIPermission; 36 import jdk.vm.ci.services.JVMCIServiceLocator; 37 import jdk.vm.ci.services.Services; 38 39 import static jdk.vm.ci.services.Services.IS_IN_NATIVE_IMAGE; 40 41 final class HotSpotJVMCICompilerConfig { 42 43 /** 44 * This factory allows JVMCI initialization to succeed but raises an error if the VM asks JVMCI 45 * to perform a compilation. This allows the reflective parts of the JVMCI API to be used 46 * without requiring a compiler implementation to be available. 47 */ 48 private static class DummyCompilerFactory implements JVMCICompilerFactory, JVMCICompiler { 49 50 private final String reason; 51 DummyCompilerFactory(String reason)52 DummyCompilerFactory(String reason) { 53 this.reason = reason; 54 } 55 56 @Override compileMethod(CompilationRequest request)57 public HotSpotCompilationRequestResult compileMethod(CompilationRequest request) { 58 throw new JVMCIError("no JVMCI compiler selected: " + reason); 59 } 60 61 @Override getCompilerName()62 public String getCompilerName() { 63 return "null"; 64 } 65 66 @Override createCompiler(JVMCIRuntime runtime)67 public JVMCICompiler createCompiler(JVMCIRuntime runtime) { 68 return this; 69 } 70 } 71 72 /** 73 * Factory of the selected system compiler. 74 */ 75 @NativeImageReinitialize private static JVMCICompilerFactory compilerFactory; 76 77 /** 78 * Gets the selected system compiler factory. 79 * 80 * @return the selected system compiler factory 81 * @throws SecurityException if a security manager is present and it denies 82 * {@link JVMCIPermission} for any {@link JVMCIServiceLocator} loaded by this method 83 */ getCompilerFactory()84 static JVMCICompilerFactory getCompilerFactory() { 85 if (compilerFactory == null) { 86 JVMCICompilerFactory factory = null; 87 String compilerName = Option.Compiler.getString(); 88 if (compilerName != null) { 89 if (compilerName.isEmpty()) { 90 factory = new DummyCompilerFactory(" empty \"\" is specified"); 91 } else if (compilerName.equals("null")) { 92 factory = new DummyCompilerFactory("\"null\" is specified"); 93 } else { 94 for (JVMCICompilerFactory f : getJVMCICompilerFactories()) { 95 if (f.getCompilerName().equals(compilerName)) { 96 factory = f; 97 } 98 } 99 if (factory == null) { 100 if (Services.IS_IN_NATIVE_IMAGE) { 101 throw new JVMCIError("JVMCI compiler '%s' not found in JVMCI native library.%n" + 102 "Use -XX:-UseJVMCINativeLibrary when specifying a JVMCI compiler available on a class path with %s.", 103 compilerName, Option.Compiler.getPropertyName()); 104 } 105 throw new JVMCIError("JVMCI compiler '%s' not found", compilerName); 106 } 107 } 108 } else { 109 // Auto select a single available compiler 110 String reason = "default compiler is not found"; 111 for (JVMCICompilerFactory f : getJVMCICompilerFactories()) { 112 if (factory == null) { 113 openJVMCITo(f.getClass().getModule()); 114 factory = f; 115 } else { 116 // Multiple factories seen - cancel auto selection 117 reason = "multiple factories seen: \"" + factory.getCompilerName() + "\" and \"" + f.getCompilerName() + "\""; 118 factory = null; 119 break; 120 } 121 } 122 if (factory == null) { 123 factory = new DummyCompilerFactory(reason); 124 } 125 } 126 factory.onSelection(); 127 compilerFactory = factory; 128 } 129 return compilerFactory; 130 } 131 132 /** 133 * Opens all JVMCI packages to {@code otherModule}. 134 */ openJVMCITo(Module otherModule)135 private static void openJVMCITo(Module otherModule) { 136 if (!IS_IN_NATIVE_IMAGE) { 137 Module jvmci = HotSpotJVMCICompilerConfig.class.getModule(); 138 if (jvmci != otherModule) { 139 Set<String> packages = jvmci.getPackages(); 140 for (String pkg : packages) { 141 boolean opened = jvmci.isOpen(pkg, otherModule); 142 if (!opened) { 143 jvmci.addOpens(pkg, otherModule); 144 } 145 } 146 } 147 } 148 } 149 getJVMCICompilerFactories()150 private static List<JVMCICompilerFactory> getJVMCICompilerFactories() { 151 return JVMCIServiceLocator.getProviders(JVMCICompilerFactory.class); 152 } 153 } 154