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 24 25 package org.graalvm.compiler.serviceprovider; 26 27 import static java.lang.Thread.currentThread; 28 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.util.Iterator; 32 import java.util.List; 33 import java.util.ServiceConfigurationError; 34 import java.util.ServiceLoader; 35 import java.util.concurrent.atomic.AtomicLong; 36 37 import jdk.vm.ci.runtime.JVMCI; 38 import jdk.vm.ci.services.JVMCIPermission; 39 import jdk.vm.ci.services.Services; 40 41 /** 42 * Interface to functionality that abstracts over which JDK version Graal is running on. 43 */ 44 public final class GraalServices { 45 46 private static int getJavaSpecificationVersion() { 47 String value = System.getProperty("java.specification.version"); 48 if (value.startsWith("1.")) { 49 value = value.substring(2); 50 } 51 return Integer.parseInt(value); 52 } 53 54 /** 55 * The integer value corresponding to the value of the {@code java.specification.version} system 56 * property after any leading {@code "1."} has been stripped. 57 */ 58 public static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion(); 59 60 /** 61 * Determines if the Java runtime is version 8 or earlier. 62 */ 63 public static final boolean Java8OrEarlier = JAVA_SPECIFICATION_VERSION <= 8; 64 65 /** 66 * Determines if the Java runtime is version 11 or earlier. 67 */ 68 public static final boolean Java11OrEarlier = JAVA_SPECIFICATION_VERSION <= 11; 69 70 private GraalServices() { 71 } 72 73 /** 74 * Gets an {@link Iterable} of the providers available for a given service. 75 * 76 * @throws SecurityException if on JDK8 and a security manager is present and it denies 77 * {@link JVMCIPermission} 78 */ 79 public static <S> Iterable<S> load(Class<S> service) { 80 Iterable<S> iterable = ServiceLoader.load(service); 81 return new Iterable<>() { 82 @Override 83 public Iterator<S> iterator() { 84 Iterator<S> iterator = iterable.iterator(); 85 return new Iterator<>() { 86 @Override 87 public boolean hasNext() { 88 return iterator.hasNext(); 89 } 175 * A JVMCI package dynamically exported to trusted modules. 176 */ 177 private static final String JVMCI_RUNTIME_PACKAGE = "jdk.vm.ci.runtime"; 178 static { 179 assert JVMCI_MODULE.getPackages().contains(JVMCI_RUNTIME_PACKAGE); 180 } 181 182 /** 183 * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run 184 * trusted code. 185 */ 186 public static boolean isToStringTrusted(Class<?> c) { 187 Module module = c.getModule(); 188 Module jvmciModule = JVMCI_MODULE; 189 assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime"); 190 if (module == jvmciModule || jvmciModule.isOpen(JVMCI_RUNTIME_PACKAGE, module)) { 191 // Can access non-statically-exported package in JVMCI 192 return true; 193 } 194 return false; 195 } 196 197 /** 198 * Gets a unique identifier for this execution such as a process ID or a 199 * {@linkplain #getGlobalTimeStamp() fixed timestamp}. 200 */ 201 public static String getExecutionID() { 202 return Long.toString(ProcessHandle.current().pid()); 203 } 204 205 private static final AtomicLong globalTimeStamp = new AtomicLong(); 206 207 /** 208 * Gets a time stamp for the current process. This method will always return the same value for 209 * the current VM execution. 210 */ 211 public static long getGlobalTimeStamp() { 212 if (globalTimeStamp.get() == 0) { 213 globalTimeStamp.compareAndSet(0, System.currentTimeMillis()); 214 } | 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 24 25 package org.graalvm.compiler.serviceprovider; 26 27 import static java.lang.Thread.currentThread; 28 29 import java.io.IOException; 30 import java.io.InputStream; 31 import java.util.Arrays; 32 import java.util.Iterator; 33 import java.util.List; 34 import java.util.ServiceConfigurationError; 35 import java.util.ServiceLoader; 36 import java.util.concurrent.atomic.AtomicLong; 37 38 import jdk.vm.ci.meta.SpeculationLog.SpeculationReason; 39 import jdk.vm.ci.runtime.JVMCI; 40 import jdk.vm.ci.services.JVMCIPermission; 41 import jdk.vm.ci.services.Services; 42 43 /** 44 * Interface to functionality that abstracts over which JDK version Graal is running on. 45 */ 46 public final class GraalServices { 47 48 private GraalServices() { 49 } 50 51 /** 52 * Gets an {@link Iterable} of the providers available for a given service. 53 * 54 * @throws SecurityException if on JDK8 and a security manager is present and it denies 55 * {@link JVMCIPermission} 56 */ 57 public static <S> Iterable<S> load(Class<S> service) { 58 Iterable<S> iterable = ServiceLoader.load(service); 59 return new Iterable<>() { 60 @Override 61 public Iterator<S> iterator() { 62 Iterator<S> iterator = iterable.iterator(); 63 return new Iterator<>() { 64 @Override 65 public boolean hasNext() { 66 return iterator.hasNext(); 67 } 153 * A JVMCI package dynamically exported to trusted modules. 154 */ 155 private static final String JVMCI_RUNTIME_PACKAGE = "jdk.vm.ci.runtime"; 156 static { 157 assert JVMCI_MODULE.getPackages().contains(JVMCI_RUNTIME_PACKAGE); 158 } 159 160 /** 161 * Determines if invoking {@link Object#toString()} on an instance of {@code c} will only run 162 * trusted code. 163 */ 164 public static boolean isToStringTrusted(Class<?> c) { 165 Module module = c.getModule(); 166 Module jvmciModule = JVMCI_MODULE; 167 assert jvmciModule.getPackages().contains("jdk.vm.ci.runtime"); 168 if (module == jvmciModule || jvmciModule.isOpen(JVMCI_RUNTIME_PACKAGE, module)) { 169 // Can access non-statically-exported package in JVMCI 170 return true; 171 } 172 return false; 173 } 174 175 /** 176 * An implementation of {@link SpeculationReason} based on direct, unencoded values. 177 */ 178 static final class DirectSpeculationReason implements SpeculationReason { 179 final int groupId; 180 final String groupName; 181 final Object[] context; 182 183 DirectSpeculationReason(int groupId, String groupName, Object[] context) { 184 this.groupId = groupId; 185 this.groupName = groupName; 186 this.context = context; 187 } 188 189 @Override 190 public boolean equals(Object obj) { 191 if (obj instanceof DirectSpeculationReason) { 192 DirectSpeculationReason that = (DirectSpeculationReason) obj; 193 return this.groupId == that.groupId && Arrays.equals(this.context, that.context); 194 } 195 return false; 196 } 197 198 @Override 199 public int hashCode() { 200 return groupId + Arrays.hashCode(this.context); 201 } 202 203 @Override 204 public String toString() { 205 return String.format("%s@%d%s", groupName, groupId, Arrays.toString(context)); 206 } 207 } 208 209 static SpeculationReason createSpeculationReason(int groupId, String groupName, Object... context) { 210 return new DirectSpeculationReason(groupId, groupName, context); 211 } 212 213 /** 214 * Gets a unique identifier for this execution such as a process ID or a 215 * {@linkplain #getGlobalTimeStamp() fixed timestamp}. 216 */ 217 public static String getExecutionID() { 218 return Long.toString(ProcessHandle.current().pid()); 219 } 220 221 private static final AtomicLong globalTimeStamp = new AtomicLong(); 222 223 /** 224 * Gets a time stamp for the current process. This method will always return the same value for 225 * the current VM execution. 226 */ 227 public static long getGlobalTimeStamp() { 228 if (globalTimeStamp.get() == 0) { 229 globalTimeStamp.compareAndSet(0, System.currentTimeMillis()); 230 } |