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 org.graalvm.compiler.hotspot.test; 24 25 import static org.graalvm.compiler.core.common.util.Util.JAVA_SPECIFICATION_VERSION; 26 27 import java.lang.reflect.Method; 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.Collections; 32 import java.util.HashMap; 33 import java.util.List; 34 import java.util.Map; 35 import java.util.Set; 36 import java.util.TreeSet; 37 import java.util.stream.Collectors; 38 39 import org.junit.Test; 40 41 import org.graalvm.compiler.api.test.Graal; 42 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 43 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; 44 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 45 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; 46 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; 47 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; 48 import org.graalvm.compiler.runtime.RuntimeProvider; 49 import org.graalvm.compiler.test.GraalTest; 50 51 import jdk.vm.ci.hotspot.HotSpotVMConfigStore; 52 import jdk.vm.ci.hotspot.VMIntrinsicMethod; 53 import jdk.vm.ci.meta.MetaAccessProvider; 54 import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod; 55 import jdk.vm.ci.meta.ResolvedJavaMethod; 56 57 /** 58 * Checks the set of intrinsics implemented by Graal against the set of intrinsics declared by 59 * HotSpot. The purpose of this test is to detect when new intrinsics are added to HotSpot and 60 * process them appropriately in Graal. This will be achieved by working through 61 * {@link #TO_BE_INVESTIGATED} and either implementing the intrinsic or moving it to {@link #IGNORE} 62 * . 63 */ 64 public class CheckGraalIntrinsics extends GraalTest { 65 66 public static boolean match(ResolvedJavaMethod method, VMIntrinsicMethod intrinsic) { 67 if (intrinsic.name.equals(method.getName())) { 68 if (intrinsic.descriptor.equals(method.getSignature().toMethodDescriptor())) { 69 String declaringClass = method.getDeclaringClass().toClassName().replace('.', '/'); 70 if (declaringClass.equals(intrinsic.declaringClass)) { 71 return true; 72 } 73 } 74 } 75 return false; 76 } 77 78 private static ResolvedJavaMethod findMethod(Set<ResolvedJavaMethod> methods, VMIntrinsicMethod intrinsic) { 79 for (ResolvedJavaMethod method : methods) { 80 if (match(method, intrinsic)) { 81 return method; 82 } 83 } 84 return null; 85 } 86 87 private static ResolvedJavaMethod resolveIntrinsic(MetaAccessProvider metaAccess, VMIntrinsicMethod intrinsic) throws ClassNotFoundException { 88 Class<?> c = Class.forName(intrinsic.declaringClass.replace('/', '.'), false, CheckGraalIntrinsics.class.getClassLoader()); 89 for (Method javaMethod : c.getDeclaredMethods()) { 90 if (javaMethod.getName().equals(intrinsic.name)) { 91 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(javaMethod); 92 if (intrinsic.descriptor.equals("*")) { 93 // Signature polymorphic method - name match is enough 94 return method; 95 } else { 96 if (method.getSignature().toMethodDescriptor().equals(intrinsic.descriptor)) { 97 return method; 98 } 99 } 100 } 101 } 102 return null; 103 } 104 105 /** 106 * The HotSpot intrinsics implemented without {@link InvocationPlugin}s or whose 107 * {@link InvocationPlugin} registration is guarded by a condition that is false in the current 408 add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I"); 409 } 410 } 411 } 412 413 private static String getHostArchitectureName() { 414 String arch = System.getProperty("os.arch"); 415 if (arch.equals("x86_64")) { 416 arch = "amd64"; 417 } else if (arch.equals("sparcv9")) { 418 arch = "sparc"; 419 } 420 return arch; 421 } 422 423 @Test 424 @SuppressWarnings("try") 425 public void test() throws ClassNotFoundException { 426 HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class); 427 HotSpotProviders providers = rt.getHostBackend().getProviders(); 428 Map<ResolvedJavaMethod, Object> impl = new HashMap<>(); 429 Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins(); 430 InvocationPlugins invocationPlugins = graphBuilderPlugins.getInvocationPlugins(); 431 for (ResolvedJavaMethod method : invocationPlugins.getMethods()) { 432 InvocationPlugin plugin = invocationPlugins.lookupInvocation(method); 433 assert plugin != null; 434 impl.put(method, plugin); 435 } 436 437 Set<ResolvedJavaMethod> methods = invocationPlugins.getMethods(); 438 HotSpotVMConfigStore store = rt.getVMConfig().getStore(); 439 List<VMIntrinsicMethod> intrinsics = store.getIntrinsics(); 440 441 List<String> missing = new ArrayList<>(); 442 for (VMIntrinsicMethod intrinsic : intrinsics) { 443 ResolvedJavaMethod method = findMethod(methods, intrinsic); 444 if (method == null) { 445 method = resolveIntrinsic(providers.getMetaAccess(), intrinsic); 446 447 IntrinsicMethod intrinsicMethod = null; 448 if (method != null) { 449 intrinsicMethod = providers.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(method); 450 if (intrinsicMethod != null) { 451 continue; 452 } 453 } 454 String m = String.format("%s.%s%s", intrinsic.declaringClass, intrinsic.name, intrinsic.descriptor); 455 if (!TO_BE_INVESTIGATED.contains(m) && !IGNORE.contains(m)) { 456 missing.add(m); 457 } 458 } 459 } 460 461 if (!missing.isEmpty()) { 462 Collections.sort(missing); 463 String missingString = missing.stream().collect(Collectors.joining(String.format("%n "))); 464 fail("missing Graal intrinsics for:%n %s", missingString); 465 } 466 } 467 } | 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 org.graalvm.compiler.hotspot.test; 24 25 import static org.graalvm.compiler.core.common.util.Util.JAVA_SPECIFICATION_VERSION; 26 27 import java.lang.reflect.Method; 28 import java.util.ArrayList; 29 import java.util.Arrays; 30 import java.util.Collection; 31 import java.util.Collections; 32 import java.util.List; 33 import java.util.Map; 34 import java.util.Set; 35 import java.util.TreeSet; 36 import java.util.stream.Collectors; 37 38 import org.graalvm.compiler.api.test.Graal; 39 import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; 40 import org.graalvm.compiler.hotspot.HotSpotGraalRuntimeProvider; 41 import org.graalvm.compiler.hotspot.meta.HotSpotProviders; 42 import org.graalvm.compiler.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; 43 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugin; 44 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins; 45 import org.graalvm.compiler.nodes.graphbuilderconf.InvocationPlugins.Binding; 46 import org.graalvm.compiler.runtime.RuntimeProvider; 47 import org.graalvm.compiler.test.GraalTest; 48 import org.junit.Test; 49 50 import jdk.vm.ci.hotspot.HotSpotVMConfigStore; 51 import jdk.vm.ci.hotspot.VMIntrinsicMethod; 52 import jdk.vm.ci.meta.MetaAccessProvider; 53 import jdk.vm.ci.meta.MetaUtil; 54 import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod; 55 import jdk.vm.ci.meta.ResolvedJavaMethod; 56 57 /** 58 * Checks the set of intrinsics implemented by Graal against the set of intrinsics declared by 59 * HotSpot. The purpose of this test is to detect when new intrinsics are added to HotSpot and 60 * process them appropriately in Graal. This will be achieved by working through 61 * {@link #TO_BE_INVESTIGATED} and either implementing the intrinsic or moving it to {@link #IGNORE} 62 * . 63 */ 64 public class CheckGraalIntrinsics extends GraalTest { 65 66 public static boolean match(String type, Binding binding, VMIntrinsicMethod intrinsic) { 67 if (intrinsic.name.equals(binding.name)) { 68 if (intrinsic.descriptor.startsWith(binding.argumentsDescriptor)) { 69 if (type.equals(intrinsic.declaringClass)) { 70 return true; 71 } 72 } 73 } 74 return false; 75 } 76 77 public static InvocationPlugin findPlugin(Map<String, List<Binding>> bindings, VMIntrinsicMethod intrinsic) { 78 for (Map.Entry<String, List<Binding>> e : bindings.entrySet()) { 79 // Match format of VMIntrinsicMethod.declaringClass 80 String type = MetaUtil.internalNameToJava(e.getKey(), true, false).replace('.', '/'); 81 for (Binding binding : e.getValue()) { 82 if (match(type, binding, intrinsic)) { 83 return binding.plugin; 84 } 85 } 86 } 87 return null; 88 } 89 90 public static ResolvedJavaMethod resolveIntrinsic(MetaAccessProvider metaAccess, VMIntrinsicMethod intrinsic) throws ClassNotFoundException { 91 Class<?> c = Class.forName(intrinsic.declaringClass.replace('/', '.'), false, CheckGraalIntrinsics.class.getClassLoader()); 92 for (Method javaMethod : c.getDeclaredMethods()) { 93 if (javaMethod.getName().equals(intrinsic.name)) { 94 ResolvedJavaMethod method = metaAccess.lookupJavaMethod(javaMethod); 95 if (intrinsic.descriptor.equals("*")) { 96 // Signature polymorphic method - name match is enough 97 return method; 98 } else { 99 if (method.getSignature().toMethodDescriptor().equals(intrinsic.descriptor)) { 100 return method; 101 } 102 } 103 } 104 } 105 return null; 106 } 107 108 /** 109 * The HotSpot intrinsics implemented without {@link InvocationPlugin}s or whose 110 * {@link InvocationPlugin} registration is guarded by a condition that is false in the current 411 add(IGNORE, "java/math/BigInteger.implMultiplyToLen([II[II[I)[I"); 412 } 413 } 414 } 415 416 private static String getHostArchitectureName() { 417 String arch = System.getProperty("os.arch"); 418 if (arch.equals("x86_64")) { 419 arch = "amd64"; 420 } else if (arch.equals("sparcv9")) { 421 arch = "sparc"; 422 } 423 return arch; 424 } 425 426 @Test 427 @SuppressWarnings("try") 428 public void test() throws ClassNotFoundException { 429 HotSpotGraalRuntimeProvider rt = (HotSpotGraalRuntimeProvider) Graal.getRequiredCapability(RuntimeProvider.class); 430 HotSpotProviders providers = rt.getHostBackend().getProviders(); 431 Plugins graphBuilderPlugins = providers.getGraphBuilderPlugins(); 432 InvocationPlugins invocationPlugins = graphBuilderPlugins.getInvocationPlugins(); 433 434 HotSpotVMConfigStore store = rt.getVMConfig().getStore(); 435 List<VMIntrinsicMethod> intrinsics = store.getIntrinsics(); 436 437 List<String> missing = new ArrayList<>(); 438 Map<String, List<Binding>> bindings = invocationPlugins.getBindings(true); 439 for (VMIntrinsicMethod intrinsic : intrinsics) { 440 InvocationPlugin plugin = findPlugin(bindings, intrinsic); 441 if (plugin == null) { 442 ResolvedJavaMethod method = resolveIntrinsic(providers.getMetaAccess(), intrinsic); 443 if (method != null) { 444 IntrinsicMethod intrinsicMethod = providers.getConstantReflection().getMethodHandleAccess().lookupMethodHandleIntrinsic(method); 445 if (intrinsicMethod != null) { 446 continue; 447 } 448 } 449 String m = String.format("%s.%s%s", intrinsic.declaringClass, intrinsic.name, intrinsic.descriptor); 450 if (!TO_BE_INVESTIGATED.contains(m) && !IGNORE.contains(m)) { 451 missing.add(m); 452 } 453 } 454 } 455 456 if (!missing.isEmpty()) { 457 Collections.sort(missing); 458 String missingString = missing.stream().collect(Collectors.joining(String.format("%n "))); 459 fail("missing Graal intrinsics for:%n %s", missingString); 460 } 461 } 462 } |