1 /* 2 * Copyright (c) 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 24 25 package org.graalvm.compiler.replacements.test; 26 27 import static org.graalvm.compiler.test.SubprocessUtil.getVMCommandLine; 28 import static org.graalvm.compiler.test.SubprocessUtil.withoutDebuggerArguments; 29 30 import org.junit.Test; 31 import org.objectweb.asm.ClassWriter; 32 import org.objectweb.asm.MethodVisitor; 33 import org.objectweb.asm.Type; 34 35 import java.io.File; 36 import java.lang.invoke.MethodHandles; 37 import java.util.List; 38 39 import org.graalvm.compiler.core.test.CustomizedBytecodePatternTest; 40 import org.graalvm.compiler.test.SubprocessUtil; 41 import org.graalvm.compiler.test.SubprocessUtil.Subprocess; 42 43 import jdk.vm.ci.meta.ResolvedJavaMethod; 44 45 public class InvokerSignatureMismatchTest { 46 47 @Test 48 public void test() throws Throwable { 49 List<String> args = withoutDebuggerArguments(getVMCommandLine()); 50 String classPath = System.getProperty("java.class.path"); 51 classPath = classPath + File.pathSeparator + TestISMBL.class.getProtectionDomain().getCodeSource().getLocation().getPath(); 52 args.add("-Xbootclasspath/a:" + classPath); 53 args.add("-XX:-TieredCompilation"); 54 args.add("-XX:+EnableJVMCI"); 55 args.add("-XX:+UseJVMCICompiler"); 56 57 args.add(TestISMBL.class.getName()); 58 Subprocess proc = SubprocessUtil.java(args); 59 if (proc.exitCode != 0) { 60 System.out.println(proc); 61 } 62 } 63 } 64 65 class TestISMBL extends CustomizedBytecodePatternTest { 66 67 public static void main(String[] args) { 68 try { 69 new TestISMBL().test(); 70 } catch (Throwable e) { 71 e.printStackTrace(); 72 System.exit(1); 73 } 74 System.exit(0); 75 } 76 77 private void test() throws Throwable { 78 getClass("java/lang/invoke/MHHelper"); 79 Class<?> testClass = getClass("ISMTest"); 80 81 ResolvedJavaMethod mL = getResolvedJavaMethod(testClass, "mainLink"); 82 ResolvedJavaMethod mI = getResolvedJavaMethod(testClass, "mainInvoke"); 83 executeActual(mL, null, 100); 84 executeActual(mI, null, 100); 85 } 86 87 @Override 88 protected Class<?> getClass(String className) throws ClassNotFoundException { 89 if (className.equals("java/lang/invoke/MHHelper")) { 90 return super.getClassBL(className, MethodHandles.lookup()); 91 } else { 92 return super.getClass(className); 93 } 94 } 95 96 @Override 97 protected byte[] generateClass(String className) { 98 String[] exceptions = new String[]{"java/lang/Throwable"}; 99 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); 100 cw.visit(52, ACC_SUPER | ACC_PUBLIC, className, null, "java/lang/Object", null); 101 102 if (className.equals("java/lang/invoke/MHHelper")) { 103 MethodVisitor internalMemberName = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", null, exceptions); 104 internalMemberName.visitCode(); 105 internalMemberName.visitVarInsn(ALOAD, 0); 106 internalMemberName.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "internalMemberName", "()Ljava/lang/invoke/MemberName;", false); 107 internalMemberName.visitInsn(ARETURN); 108 internalMemberName.visitMaxs(1, 1); 109 internalMemberName.visitEnd(); 110 111 MethodVisitor linkToStatic = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "linkToStatic", "(FLjava/lang/Object;)I", null, exceptions); 112 linkToStatic.visitCode(); 113 linkToStatic.visitVarInsn(FLOAD, 0); 114 linkToStatic.visitVarInsn(ALOAD, 1); 115 linkToStatic.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandle", "linkToStatic", "(FLjava/lang/Object;)I", false); 116 linkToStatic.visitInsn(IRETURN); 117 linkToStatic.visitMaxs(1, 1); 118 linkToStatic.visitEnd(); 119 120 MethodVisitor invokeBasicI = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", null, exceptions); 121 invokeBasicI.visitCode(); 122 invokeBasicI.visitVarInsn(ALOAD, 0); 123 invokeBasicI.visitVarInsn(FLOAD, 1); 124 invokeBasicI.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandle", "invokeBasic", "(F)I", false); 125 invokeBasicI.visitInsn(IRETURN); 126 invokeBasicI.visitMaxs(1, 1); 127 invokeBasicI.visitEnd(); 128 129 } else { 130 assert className.equals("ISMTest") : className; 131 cw.visitField(ACC_FINAL | ACC_STATIC, "INT_MH", "Ljava/lang/invoke/MethodHandle;", null, null).visitAnnotation("Ljava/lang/invoke/Stable.class;", true).visitEnd(); 132 MethodVisitor clinit = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, exceptions); 133 clinit.visitCode(); 134 clinit.visitInsn(ACONST_NULL); 135 clinit.visitVarInsn(ASTORE, 0); 136 clinit.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodHandles", "lookup", "()Ljava/lang/invoke/MethodHandles$Lookup;", false); 137 clinit.visitLdcInsn(Type.getObjectType(className)); 138 clinit.visitLdcInsn("bodyI"); 139 clinit.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); 140 clinit.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); 141 clinit.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MethodType", "methodType", "(Ljava/lang/Class;Ljava/lang/Class;)Ljava/lang/invoke/MethodType;", false); 142 clinit.visitMethodInsn(INVOKEVIRTUAL, "java/lang/invoke/MethodHandles$Lookup", "findStatic", 143 "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/MethodHandle;", false); 144 clinit.visitFieldInsn(PUTSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); 145 clinit.visitInsn(RETURN); 146 clinit.visitMaxs(1, 1); 147 clinit.visitEnd(); 148 149 MethodVisitor mainLink = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainLink", "(I)I", null, exceptions); 150 mainLink.visitCode(); 151 mainLink.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); 152 mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "internalMemberName", "(Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;", false); 153 mainLink.visitVarInsn(ASTORE, 1); 154 mainLink.visitVarInsn(ILOAD, 0); 155 mainLink.visitInsn(I2F); 156 mainLink.visitVarInsn(ALOAD, 1); 157 mainLink.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "linkToStatic", "(FLjava/lang/Object;)I", false); 158 mainLink.visitInsn(IRETURN); 159 mainLink.visitMaxs(1, 1); 160 mainLink.visitEnd(); 161 162 MethodVisitor mainInvoke = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "mainInvoke", "(I)I", null, exceptions); 163 mainInvoke.visitCode(); 164 mainInvoke.visitFieldInsn(GETSTATIC, className, "INT_MH", "Ljava/lang/invoke/MethodHandle;"); 165 mainInvoke.visitVarInsn(ILOAD, 0); 166 mainInvoke.visitInsn(I2F); 167 mainInvoke.visitMethodInsn(INVOKESTATIC, "java/lang/invoke/MHHelper", "invokeBasicI", "(Ljava/lang/invoke/MethodHandle;F)I", false); 168 mainInvoke.visitInsn(IRETURN); 169 mainInvoke.visitMaxs(1, 1); 170 mainInvoke.visitEnd(); 171 172 MethodVisitor bodyI = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "bodyI", "(I)I", null, null); 173 bodyI.visitCode(); 174 bodyI.visitVarInsn(ILOAD, 0); 175 bodyI.visitIntInsn(SIPUSH, 1023); 176 bodyI.visitInsn(IAND); 177 bodyI.visitInsn(IRETURN); 178 bodyI.visitMaxs(1, 1); 179 bodyI.visitEnd(); 180 } 181 cw.visitEnd(); 182 return cw.toByteArray(); 183 } 184 }