GetVtableIndexForInterfaceTest.java revision 9111:a41fe5ffa839
1133123Sjmg/* 2133123Sjmg * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 3133123Sjmg * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4133123Sjmg * 5133123Sjmg * This code is free software; you can redistribute it and/or modify it 6133123Sjmg * under the terms of the GNU General Public License version 2 only, as 7133123Sjmg * published by the Free Software Foundation. 8133123Sjmg * 9133123Sjmg * This code is distributed in the hope that it will be useful, but WITHOUT 10133123Sjmg * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11133123Sjmg * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12133123Sjmg * version 2 for more details (a copy is included in the LICENSE file that 13133123Sjmg * accompanied this code). 14133123Sjmg * 15133123Sjmg * You should have received a copy of the GNU General Public License version 16133123Sjmg * 2 along with this work; if not, write to the Free Software Foundation, 17133123Sjmg * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18133123Sjmg * 19133123Sjmg * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20133123Sjmg * or visit www.oracle.com if you need additional information or have any 21133123Sjmg * questions. 22133123Sjmg */ 23133123Sjmg 24133123Sjmg/* 25133123Sjmg * @test 26133123Sjmg * @bug 8136421 27133123Sjmg * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9") & os.arch != "aarch64" 28133123Sjmg * @library / /testlibrary /../../test/lib 29133123Sjmg * @compile ../common/CompilerToVMHelper.java 30133123Sjmg * @build compiler.jvmci.compilerToVM.GetVtableIndexForInterfaceTest 31133123Sjmg * @run main ClassFileInstaller 32133123Sjmg * jdk.vm.ci.hotspot.CompilerToVMHelper 33133123Sjmg * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockExperimentalVMOptions 34143864Sjmg * -XX:+EnableJVMCI compiler.jvmci.compilerToVM.GetVtableIndexForInterfaceTest 35133123Sjmg */ 36133123Sjmg 37133123Sjmgpackage compiler.jvmci.compilerToVM; 38133123Sjmg 39133123Sjmgimport compiler.jvmci.common.testcases.AbstractClass; 40133123Sjmgimport compiler.jvmci.common.testcases.DoNotExtendClass; 41133123Sjmgimport compiler.jvmci.common.testcases.MultipleAbstractImplementer; 42133123Sjmgimport compiler.jvmci.common.testcases.MultipleImplementersInterface; 43133123Sjmgimport compiler.jvmci.common.testcases.MultipleImplementersInterfaceExtender; 44133123Sjmgimport compiler.jvmci.common.testcases.SingleImplementer; 45133123Sjmgimport compiler.jvmci.common.testcases.SingleImplementerInterface; 46133123Sjmgimport compiler.jvmci.common.testcases.SingleSubclass; 47133123Sjmgimport compiler.jvmci.common.testcases.SingleSubclassedClass; 48133123Sjmgimport compiler.jvmci.common.CTVMUtilities; 49133123Sjmgimport compiler.jvmci.common.testcases.AnotherSingleImplementer; 50133123Sjmgimport compiler.jvmci.common.testcases.AnotherSingleImplementerInterface; 51133123Sjmgimport java.lang.reflect.Method; 52133123Sjmgimport java.util.HashSet; 53133123Sjmgimport java.util.Set; 54133123Sjmgimport java.util.stream.Stream; 55133123Sjmgimport jdk.vm.ci.hotspot.CompilerToVMHelper; 56133123Sjmgimport jdk.vm.ci.hotspot.HotSpotResolvedJavaMethodImpl; 57133123Sjmgimport jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl; 58133123Sjmgimport jdk.test.lib.Asserts; 59133123Sjmgimport jdk.test.lib.Utils; 60133123Sjmg 61133123Sjmgpublic class GetVtableIndexForInterfaceTest { 62133123Sjmg private static final int INVALID_VTABLE_INDEX = -4; // see method.hpp: VtableIndexFlag 63133123Sjmg 64143864Sjmg public static void main(String args[]) { 65133123Sjmg GetVtableIndexForInterfaceTest test 66133123Sjmg = new GetVtableIndexForInterfaceTest(); 67133123Sjmg try { 68133123Sjmg for (TestCase tcase : createTestCases()) { 69133123Sjmg test.runTest(tcase); 70133123Sjmg } 71228975Suqs } catch (NoSuchMethodException e) { 72133123Sjmg throw new Error("TEST BUG: can't find requested method", e); 73228975Suqs } 74133123Sjmg } 75133123Sjmg 76133123Sjmg private static Set<TestCase> createTestCases() { 77133123Sjmg Set<TestCase> result = new HashSet<>(); 78133123Sjmg Stream.of( 79133123Sjmg AbstractClass.class, 80133123Sjmg SingleImplementer.class, 81133123Sjmg SingleImplementerInterface.class, 82133123Sjmg MultipleImplementersInterface.class, 83133123Sjmg MultipleImplementersInterfaceExtender.class, 84133123Sjmg SingleSubclass.class, 85133123Sjmg SingleSubclassedClass.class, 86133123Sjmg DoNotExtendClass.class, 87133123Sjmg MultipleAbstractImplementer.class 88133123Sjmg ) 89133123Sjmg .forEach(Utils::ensureClassIsLoaded); 90228975Suqs // non iface method 91133123Sjmg result.add(new TestCase(SingleImplementer.class, 92133123Sjmg SingleImplementer.class, "nonInterfaceMethod", 93133123Sjmg false, InternalError.class)); 94133123Sjmg // iface method w/o default implementation 95133123Sjmg result.add(new TestCase(SingleImplementer.class, 96133123Sjmg SingleImplementerInterface.class, "interfaceMethod", false)); 97133123Sjmg /* another iface which provides default implementation for the 98133123Sjmg original iface*/ 99133123Sjmg result.add(new TestCase(MultipleImplementersInterfaceExtender.class, 100133123Sjmg MultipleImplementersInterface.class, "testMethod", false, 101133123Sjmg InternalError.class)); 102133123Sjmg // iface method w/ default implementation 103133123Sjmg result.add(new TestCase(SingleImplementer.class, 104133123Sjmg SingleImplementerInterface.class, "defaultMethod", true)); 105133123Sjmg // non iface class 106133123Sjmg result.add(new TestCase(SingleSubclass.class, 107133123Sjmg SingleSubclassedClass.class, "inheritedMethod", false, 108133123Sjmg InternalError.class)); 109133123Sjmg // class not implementing iface 110133123Sjmg result.add(new TestCase(DoNotExtendClass.class, 111133123Sjmg SingleImplementerInterface.class, "defaultMethod", false)); 112133123Sjmg // abstract class which doesn't implement iface 113133123Sjmg result.add(new TestCase(AbstractClass.class, 114133123Sjmg SingleImplementerInterface.class, "defaultMethod", false)); 115133123Sjmg // abstract class which implements iface 116133123Sjmg result.add(new TestCase(MultipleAbstractImplementer.class, 117133123Sjmg MultipleImplementersInterface.class, "defaultMethod", true)); 118133123Sjmg // class not initialized 119133123Sjmg result.add(new TestCase(AnotherSingleImplementer.class, 120133123Sjmg AnotherSingleImplementerInterface.class, "defaultMethod", 121133123Sjmg false, InternalError.class)); 122133123Sjmg return result; 123133123Sjmg } 124133123Sjmg 125133123Sjmg private void runTest(TestCase tcase) throws NoSuchMethodException { 126133123Sjmg System.out.println(tcase); 127133123Sjmg Method method = tcase.holder.getDeclaredMethod(tcase.methodName); 128133123Sjmg HotSpotResolvedObjectTypeImpl metaspaceKlass = CompilerToVMHelper 129133123Sjmg .lookupType(Utils.toJVMTypeSignature(tcase.receiver), 130133123Sjmg getClass(), /* resolve = */ true); 131133123Sjmg HotSpotResolvedJavaMethodImpl metaspaceMethod = CTVMUtilities 132133123Sjmg .getResolvedMethod(tcase.holder, method); 133133123Sjmg int index = 0; 134133123Sjmg try { 135133123Sjmg index = CompilerToVMHelper 136133123Sjmg .getVtableIndexForInterfaceMethod(metaspaceKlass, 137133123Sjmg metaspaceMethod); 138133123Sjmg } catch (Throwable t) { 139133123Sjmg if (tcase.isPositive || tcase.expectedException == null) { 140133123Sjmg throw new Error("Caught unexpected exception " + t); 141133123Sjmg } 142133123Sjmg if (!tcase.expectedException.equals(t.getClass())) { 143 throw new Error(String.format("Caught %s while expected %s", 144 t.getClass().getName(), 145 tcase.expectedException.getName())); 146 } 147 return; 148 } 149 if (tcase.expectedException != null) { 150 throw new AssertionError("Expected exception wasn't caught: " 151 + tcase.expectedException.getName()); 152 } 153 if (tcase.isPositive) { 154 Asserts.assertNE(index, INVALID_VTABLE_INDEX, 155 "Unexpected: got invalid index"); 156 } else { 157 Asserts.assertEQ(index, INVALID_VTABLE_INDEX, 158 "Unexpected: got valid index "); 159 } 160 } 161 162 private static class TestCase { 163 public final Class<?> receiver; 164 public final Class<?> holder; 165 public final String methodName; 166 public final boolean isPositive; 167 public final Class<? extends Throwable> expectedException; 168 169 public TestCase(Class<?> receiver, Class<?> holder, String methodName, 170 boolean isPositive, 171 Class<? extends Throwable> expectedException) { 172 this.receiver = receiver; 173 this.holder = holder; 174 this.methodName = methodName; 175 this.isPositive = isPositive; 176 this.expectedException = expectedException; 177 } 178 179 public TestCase(Class<?> receiver, Class<?> holder, String methodName, 180 boolean isPositive) { 181 this(receiver, holder, methodName, isPositive, null); 182 } 183 184 @Override 185 public String toString() { 186 return String.format("CASE: receiver=%s, holder=%s, method=%s," 187 + " isPositive=%s%n", receiver.getName(), holder.getName(), 188 methodName, isPositive); 189 } 190 } 191} 192