Mon, 01 Apr 2019 14:52:38 +0800
#8802 Backport the testcase of 8197405: Improve messages of AbstractMethodErrors and IncompatibleClassChangeErrors.
Reviewed-by: aoqi
Contributed-by: goetz
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AME1_E.jasm Mon Apr 01 14:52:38 2019 +0800 1.3 @@ -0,0 +1,112 @@ 1.4 +/* 1.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + */ 1.27 + 1.28 +/* Method aFunctionOfMyInterface:"()Ljava/lang/String;" is missing in this implementation to cause error. */ 1.29 + 1.30 +class AME1_E extends AME1_B implements AME1_C { 1.31 + 1.32 + public Method "<init>":"()V" 1.33 + stack 1 locals 1 1.34 + { 1.35 + aload_0; 1.36 + invokespecial Method AME1_B."<init>":"()V"; 1.37 + return; 1.38 + } 1.39 + 1.40 + public Method firstAbstractMethod:"()Ljava/lang/String;" 1.41 + stack 1 locals 1 1.42 + { 1.43 + aload_0; 1.44 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.45 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.46 + areturn; 1.47 + } 1.48 + 1.49 + public Method secondAbstractMethod:"()Ljava/lang/String;" 1.50 + stack 1 locals 1 1.51 + { 1.52 + aload_0; 1.53 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.54 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.55 + areturn; 1.56 + } 1.57 + 1.58 + /* Missing to cause error. 1.59 + public Method anAbstractMethod:"()Ljava/lang/String;" 1.60 + stack 1 locals 1 1.61 + { 1.62 + aload_0; 1.63 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.64 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.65 + areturn; 1.66 + } 1.67 + */ 1.68 + 1.69 + public Method firstFunctionOfMyInterface0:"()Ljava/lang/String;" 1.70 + stack 1 locals 1 1.71 + { 1.72 + aload_0; 1.73 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.74 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.75 + areturn; 1.76 + } 1.77 + 1.78 + public Method secondFunctionOfMyInterface0:"()Ljava/lang/String;" 1.79 + stack 1 locals 1 1.80 + { 1.81 + aload_0; 1.82 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.83 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.84 + areturn; 1.85 + } 1.86 + 1.87 + public Method firstFunctionOfMyInterface:"()Ljava/lang/String;" 1.88 + stack 1 locals 1 1.89 + { 1.90 + aload_0; 1.91 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.92 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.93 + areturn; 1.94 + } 1.95 + 1.96 + public Method secondFunctionOfMyInterface:"()Ljava/lang/String;" 1.97 + stack 1 locals 1 1.98 + { 1.99 + aload_0; 1.100 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.101 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.102 + areturn; 1.103 + } 1.104 + 1.105 + /* Missing to cause error. 1.106 + public Method aFunctionOfMyInterface:"()Ljava/lang/String;" 1.107 + stack 1 locals 1 1.108 + { 1.109 + aload_0; 1.110 + invokevirtual Method java/lang/Object.getClass:"()Ljava/lang/Class;"; 1.111 + invokevirtual Method java/lang/Class.getName:"()Ljava/lang/String;"; 1.112 + areturn; 1.113 + } 1.114 + */ 1.115 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AME2_C.jasm Mon Apr 01 14:52:38 2019 +0800 2.3 @@ -0,0 +1,42 @@ 2.4 +/* 2.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 2.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 2.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.8 + * 2.9 + * This code is free software; you can redistribute it and/or modify it 2.10 + * under the terms of the GNU General Public License version 2 only, as 2.11 + * published by the Free Software Foundation. 2.12 + * 2.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.16 + * version 2 for more details (a copy is included in the LICENSE file that 2.17 + * accompanied this code). 2.18 + * 2.19 + * You should have received a copy of the GNU General Public License version 2.20 + * 2 along with this work; if not, write to the Free Software Foundation, 2.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.22 + * 2.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.24 + * or visit www.oracle.com if you need additional information or have any 2.25 + * questions. 2.26 + */ 2.27 + 2.28 +/* Method aFunctionOfMyInterface() is missing in this implementation to cause error. */ 2.29 + 2.30 +class AME2_C extends AME2_B { 2.31 + 2.32 + public Method "<init>":"()V" 2.33 + stack 1 locals 1 2.34 + { 2.35 + aload_0; 2.36 + invokespecial Method AME2_B."<init>":"()V"; 2.37 + return; 2.38 + } 2.39 + 2.40 + public Method fun2:"()V" 2.41 + stack 0 locals 1 2.42 + { 2.43 + return; 2.44 + } 2.45 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AME3_C.jasm Mon Apr 01 14:52:38 2019 +0800 3.3 @@ -0,0 +1,35 @@ 3.4 +/* 3.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 3.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 + * 3.9 + * This code is free software; you can redistribute it and/or modify it 3.10 + * under the terms of the GNU General Public License version 2 only, as 3.11 + * published by the Free Software Foundation. 3.12 + * 3.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.16 + * version 2 for more details (a copy is included in the LICENSE file that 3.17 + * accompanied this code). 3.18 + * 3.19 + * You should have received a copy of the GNU General Public License version 3.20 + * 2 along with this work; if not, write to the Free Software Foundation, 3.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.22 + * 3.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.24 + * or visit www.oracle.com if you need additional information or have any 3.25 + * questions. 3.26 + */ 3.27 + 3.28 +/* Method ma() is missing in this implementation to cause error. */ 3.29 + 3.30 +class AME3_C extends AME3_B { 3.31 + public Method "<init>":"()V" 3.32 + stack 1 locals 1 3.33 + { 3.34 + aload_0; 3.35 + invokespecial Method AME3_B."<init>":()V; 3.36 + return; 3.37 + } 3.38 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AME4_E.jasm Mon Apr 01 14:52:38 2019 +0800 4.3 @@ -0,0 +1,36 @@ 4.4 +/* 4.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 4.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 + * 4.9 + * This code is free software; you can redistribute it and/or modify it 4.10 + * under the terms of the GNU General Public License version 2 only, as 4.11 + * published by the Free Software Foundation. 4.12 + * 4.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.16 + * version 2 for more details (a copy is included in the LICENSE file that 4.17 + * accompanied this code). 4.18 + * 4.19 + * You should have received a copy of the GNU General Public License version 4.20 + * 2 along with this work; if not, write to the Free Software Foundation, 4.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.22 + * 4.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.24 + * or visit www.oracle.com if you need additional information or have any 4.25 + * questions. 4.26 + */ 4.27 + 4.28 + 4.29 +/* Method ma() is missing in this implementation to cause error. */ 4.30 + 4.31 +class AME4_E extends AME4_B { 4.32 + public Method "<init>":"()V" 4.33 + stack 1 locals 1 4.34 + { 4.35 + aload_0; 4.36 + invokespecial Method AME4_B."<init>":()V; 4.37 + return; 4.38 + } 4.39 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AME5_B.jasm Mon Apr 01 14:52:38 2019 +0800 5.3 @@ -0,0 +1,53 @@ 5.4 +/* 5.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 5.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 + * 5.9 + * This code is free software; you can redistribute it and/or modify it 5.10 + * under the terms of the GNU General Public License version 2 only, as 5.11 + * published by the Free Software Foundation. 5.12 + * 5.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.16 + * version 2 for more details (a copy is included in the LICENSE file that 5.17 + * accompanied this code). 5.18 + * 5.19 + * You should have received a copy of the GNU General Public License version 5.20 + * 2 along with this work; if not, write to the Free Software Foundation, 5.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.22 + * 5.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.24 + * or visit www.oracle.com if you need additional information or have any 5.25 + * questions. 5.26 + */ 5.27 + 5.28 +/* Method mc() is missing in this implementation to cause error. */ 5.29 + 5.30 +class AME5_B extends AME5_A { 5.31 + public Method "<init>":"()V" 5.32 + stack 1 locals 1 5.33 + { 5.34 + aload_0; 5.35 + invokespecial Method AME5_A."<init>":()V; 5.36 + return; 5.37 + } 5.38 + 5.39 + public Method ma:"()V" 5.40 + stack 2 locals 1 5.41 + { 5.42 + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; 5.43 + ldc String "B.ma() "; 5.44 + invokevirtual Method java/io/PrintStream.print:"(Ljava/lang/String;)V"; 5.45 + return; 5.46 + } 5.47 + 5.48 + public Method mb:"()V" 5.49 + stack 2 locals 1 5.50 + { 5.51 + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; 5.52 + ldc String "B.mb() "; 5.53 + invokevirtual Method java/io/PrintStream.print:"(Ljava/lang/String;)V"; 5.54 + return; 5.55 + } 5.56 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AME6_B.jasm Mon Apr 01 14:52:38 2019 +0800 6.3 @@ -0,0 +1,53 @@ 6.4 +/* 6.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 6.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 + * 6.9 + * This code is free software; you can redistribute it and/or modify it 6.10 + * under the terms of the GNU General Public License version 2 only, as 6.11 + * published by the Free Software Foundation. 6.12 + * 6.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.16 + * version 2 for more details (a copy is included in the LICENSE file that 6.17 + * accompanied this code). 6.18 + * 6.19 + * You should have received a copy of the GNU General Public License version 6.20 + * 2 along with this work; if not, write to the Free Software Foundation, 6.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.22 + * 6.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.24 + * or visit www.oracle.com if you need additional information or have any 6.25 + * questions. 6.26 + */ 6.27 + 6.28 +/* Method mc() is missing in this implementation to cause error. */ 6.29 + 6.30 +class AME6_B implements AME6_A { 6.31 + public Method "<init>":"()V" 6.32 + stack 1 locals 1 6.33 + { 6.34 + aload_0; 6.35 + invokespecial Method java/lang/Object."<init>":"()V"; 6.36 + return; 6.37 + } 6.38 + 6.39 + public Method ma:"()V" 6.40 + stack 2 locals 1 6.41 + { 6.42 + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; 6.43 + ldc String "B.ma() "; 6.44 + invokevirtual Method java/io/PrintStream.print:"(Ljava/lang/String;)V"; 6.45 + return; 6.46 + } 6.47 + 6.48 + public Method mb:"()V" 6.49 + stack 2 locals 1 6.50 + { 6.51 + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; 6.52 + ldc String "B.mb() "; 6.53 + invokevirtual Method java/io/PrintStream.print:"(Ljava/lang/String;)V"; 6.54 + return; 6.55 + } 6.56 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 7.2 +++ b/test/runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java Mon Apr 01 14:52:38 2019 +0800 7.3 @@ -0,0 +1,884 @@ 7.4 +/* 7.5 + * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. 7.6 + * Copyright (c) 2018 SAP SE. All rights reserved. 7.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.8 + * 7.9 + * This code is free software; you can redistribute it and/or modify it 7.10 + * under the terms of the GNU General Public License version 2 only, as 7.11 + * published by the Free Software Foundation. 7.12 + * 7.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 7.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.16 + * version 2 for more details (a copy is included in the LICENSE file that 7.17 + * accompanied this code). 7.18 + * 7.19 + * You should have received a copy of the GNU General Public License version 7.20 + * 2 along with this work; if not, write to the Free Software Foundation, 7.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.22 + * 7.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.24 + * or visit www.oracle.com if you need additional information or have any 7.25 + * questions. 7.26 + */ 7.27 + 7.28 +/** 7.29 + * @test 7.30 + * @summary Check that the verbose message of the AME is printed correctly. 7.31 + * @library /testlibrary /testlibrary/whitebox /compiler/whitebox 7.32 + * @build sun.hotspot.WhiteBox 7.33 + * @run driver ClassFileInstaller sun.hotspot.WhiteBox sun.hotspot.WhiteBox$WhiteBoxPermission 7.34 + * @compile AbstractMethodErrorTest.java 7.35 + * @compile AME1_E.jasm AME2_C.jasm AME3_C.jasm AME4_E.jasm AME5_B.jasm AME6_B.jasm 7.36 + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 7.37 + * -XX:CompileThreshold=1000 -XX:-BackgroundCompilation -XX:-Inline 7.38 + * -XX:CompileCommand=exclude,AbstractMethodErrorTest::test_ame1 7.39 + * AbstractMethodErrorTest 7.40 + */ 7.41 + 7.42 +import sun.hotspot.WhiteBox; 7.43 +import java.lang.reflect.Method; 7.44 + 7.45 +// This test assembles an errorneous installation of classes. 7.46 +// First, compile the test by @compile. This results in a legal set 7.47 +// of classes. 7.48 +// Then, with jasm, generate incompatible classes that overwrite 7.49 +// the class files in the build directory. 7.50 +// Last, call the real test throwing an AbstractMethodError and 7.51 +// check the message generated. 7.52 +public class AbstractMethodErrorTest { 7.53 + 7.54 + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 7.55 + 7.56 + private static boolean enableChecks = true; 7.57 + 7.58 + private static boolean compile(Class<?> clazz, String name) { 7.59 + try { 7.60 + Method method = clazz.getMethod(name); 7.61 + boolean enqueued = WHITE_BOX.enqueueMethodForCompilation(method, CompilerWhiteBoxTest.COMP_LEVEL_FULL_OPTIMIZATION); 7.62 + if (!enqueued) { 7.63 + System.out.println("Warning: Blocking compilation failed for " + clazz.getName() + "." + name + " (timeout?)"); 7.64 + return false; 7.65 + } else if (!WHITE_BOX.isMethodCompiled(method)) { 7.66 + throw new RuntimeException(clazz.getName() + "." + name + " is not compiled"); 7.67 + } 7.68 + } catch (NoSuchMethodException e) { 7.69 + throw new RuntimeException(clazz.getName() + "." + name + " not found", e); 7.70 + } 7.71 + return true; 7.72 + } 7.73 + 7.74 + public static boolean setup_test() { 7.75 + // Assure all exceptions are loaded. 7.76 + new AbstractMethodError(); 7.77 + new IncompatibleClassChangeError(); 7.78 + 7.79 + enableChecks = false; 7.80 + // Warmup 7.81 + System.out.println("warmup:"); 7.82 + test_ame5_compiled_vtable_stub(); 7.83 + test_ame6_compiled_itable_stub(); 7.84 + enableChecks = true; 7.85 + 7.86 + // Compile 7.87 + if (!compile(AbstractMethodErrorTest.class, "test_ame5_compiled_vtable_stub") || 7.88 + !compile(AbstractMethodErrorTest.class, "test_ame6_compiled_itable_stub") || 7.89 + !compile(AME5_C.class, "mc") || 7.90 + !compile(AME5_D.class, "mc") || 7.91 + !compile(AME5_E.class, "mc") || 7.92 + !compile(AME6_C.class, "mc") || 7.93 + !compile(AME6_D.class, "mc") || 7.94 + !compile(AME6_E.class, "mc")) { 7.95 + return false; 7.96 + } 7.97 + 7.98 + System.out.println("warmup done."); 7.99 + return true; 7.100 + } 7.101 + 7.102 + private static String expectedErrorMessageAME1_1 = 7.103 + "Missing implementation of resolved method abstract " + 7.104 + "anAbstractMethod()Ljava/lang/String; of abstract class AME1_B."; 7.105 + private static String expectedErrorMessageAME1_2 = 7.106 + "Receiver class AME1_E does not define or inherit an implementation of the " + 7.107 + "resolved method abstract aFunctionOfMyInterface()Ljava/lang/String; of " + 7.108 + "interface AME1_C."; 7.109 + 7.110 + public static void test_ame1() { 7.111 + AME1_B objectAbstract = new AME1_D(); 7.112 + AME1_C objectInterface = new AME1_D(); 7.113 + objectInterface.secondFunctionOfMyInterface(); 7.114 + objectAbstract.anAbstractMethod(); 7.115 + objectInterface.aFunctionOfMyInterface(); 7.116 + 7.117 + try { 7.118 + objectAbstract = new AME1_E(); 7.119 + // AbstractMethodError gets thrown in the interpreter at: 7.120 + // InterpreterGenerator::generate_abstract_entry 7.121 + objectAbstract.anAbstractMethod(); 7.122 + throw new RuntimeException("Expected AbstractRuntimeError was not thrown."); 7.123 + } catch (AbstractMethodError e) { 7.124 + String errorMsg = e.getMessage(); 7.125 + if (errorMsg == null) { 7.126 + throw new RuntimeException("Caught AbstractMethodError with empty message."); 7.127 + } else if (!errorMsg.equals(expectedErrorMessageAME1_1)) { 7.128 + System.out.println("Expected: " + expectedErrorMessageAME1_1 + "\n" + 7.129 + "but got: " + errorMsg); 7.130 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.131 + } 7.132 + } catch (RuntimeException e) { 7.133 + throw e; 7.134 + } catch (Throwable e) { 7.135 + throw new RuntimeException("Caught unexpected exception: " + e); 7.136 + } 7.137 + 7.138 + try { 7.139 + objectInterface = new AME1_E(); 7.140 + // AbstractMethodError gets thrown in: 7.141 + // TemplateTable::invokeinterface or C-Interpreter loop 7.142 + objectInterface.aFunctionOfMyInterface(); 7.143 + throw new RuntimeException("Expected AbstractRuntimeError was not thrown."); 7.144 + } catch (AbstractMethodError e) { 7.145 + String errorMsg = e.getMessage(); 7.146 + if (errorMsg == null) { 7.147 + throw new RuntimeException("Caught AbstractMethodError with empty message."); 7.148 + } else if (!errorMsg.equals(expectedErrorMessageAME1_2)) { 7.149 + // Thrown via InterpreterRuntime::throw_AbstractMethodErrorVerbose(). 7.150 + System.out.println("Expected: " + expectedErrorMessageAME1_2 + "\n" + 7.151 + "but got: " + errorMsg); 7.152 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.153 + } else { 7.154 + System.out.println("Passed with message: " + errorMsg); 7.155 + } 7.156 + } catch (Throwable e) { 7.157 + throw new RuntimeException("Caught unexpected exception: " + e); 7.158 + } 7.159 + } 7.160 + 7.161 + private static String expectedErrorMessageAME2_Interpreted = 7.162 + "Missing implementation of resolved method abstract " + 7.163 + "aFunctionOfMyInterface()V of interface AME2_A."; 7.164 + private static String expectedErrorMessageAME2_Compiled = 7.165 + "Receiver class AME2_C does not define or inherit an implementation of the resolved method " + 7.166 + "abstract aFunctionOfMyInterface()V of interface AME2_A."; 7.167 + 7.168 + public AbstractMethodErrorTest() throws InstantiationException, IllegalAccessException { 7.169 + try { 7.170 + AME2_B myAbstract = new ImplementsAllFunctions(); 7.171 + myAbstract.fun2(); 7.172 + myAbstract.aFunctionOfMyInterface(); 7.173 + 7.174 + // AME2_C does not implement the method 7.175 + // aFunctionOfMyInterface(). Expected runtime behavior is 7.176 + // throwing an AbstractMethodError. 7.177 + // The error will be thrown via throw_AbstractMethodErrorWithMethod() 7.178 + // if the template interpreter calls an abstract method by 7.179 + // entering the abstract method entry. 7.180 + myAbstract = new AME2_C(); 7.181 + myAbstract.fun2(); 7.182 + myAbstract.aFunctionOfMyInterface(); 7.183 + } catch (SecurityException e) { 7.184 + e.printStackTrace(); 7.185 + } 7.186 + } 7.187 + 7.188 + // Loop so that method gets eventually compiled/osred. 7.189 + public static void test_ame2() throws Exception { 7.190 + boolean seenInterpreted = false; 7.191 + boolean seenCompiled = false; 7.192 + 7.193 + // Loop to test both, the interpreted and the compiled case. 7.194 + for (int i = 0; i < 10000 && !(seenInterpreted && seenCompiled); ++i) { 7.195 + try { 7.196 + // Supposed to throw AME with verbose message. 7.197 + new AbstractMethodErrorTest(); 7.198 + 7.199 + throw new RuntimeException("Expected AbstractMethodError was not thrown."); 7.200 + } catch (AbstractMethodError e) { 7.201 + String errorMsg = e.getMessage(); 7.202 + 7.203 + // Check the message obtained. 7.204 + if (errorMsg == null) { 7.205 + throw new RuntimeException("Caught AbstractMethodError with empty message."); 7.206 + } else if (errorMsg.equals(expectedErrorMessageAME2_Interpreted)) { 7.207 + seenInterpreted = true; 7.208 + } else if (errorMsg.equals(expectedErrorMessageAME2_Compiled)) { 7.209 + // Sparc and the other platforms behave differently here: 7.210 + // Sparc throws the exception via SharedRuntime::handle_wrong_method_abstract(), 7.211 + // x86, ppc and s390 via LinkResolver::runtime_resolve_virtual_method(). Thus, 7.212 + // sparc misses the test case for LinkResolver::runtime_resolve_virtual_method(). 7.213 + seenCompiled = true; 7.214 + } else { 7.215 + System.out.println("Expected: " + expectedErrorMessageAME2_Interpreted + "\n" + 7.216 + "or: " + expectedErrorMessageAME2_Compiled + "\n" + 7.217 + "but got: " + errorMsg); 7.218 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.219 + } 7.220 + } 7.221 + } 7.222 + if (!(seenInterpreted && seenCompiled)) { 7.223 + if (seenInterpreted) { System.out.println("Saw interpreted message."); } 7.224 + if (seenCompiled) { System.out.println("Saw compiled message."); } 7.225 + throw new RuntimeException("Test did not produce wrong error messages for AbstractMethodError, " + 7.226 + "but it did not test both cases (interpreted and compiled)."); 7.227 + } 7.228 + } 7.229 + 7.230 + private static String expectedErrorMessageAME3_1 = 7.231 + "Receiver class AME3_C does not define or inherit an implementation of the resolved method " + 7.232 + "ma()V of class AME3_A. Selected method is abstract AME3_B.ma()V."; 7.233 + 7.234 + // Testing abstract class that extends a class that has an implementation. 7.235 + // Loop so that method gets eventually compiled/osred. 7.236 + public static void test_ame3_1() throws Exception { 7.237 + AME3_A c = new AME3_C(); 7.238 + 7.239 + try { 7.240 + // Supposed to throw AME with verbose message. 7.241 + c.ma(); 7.242 + 7.243 + throw new RuntimeException("Expected AbstractMethodError was not thrown."); 7.244 + } catch (AbstractMethodError e) { 7.245 + String errorMsg = e.getMessage(); 7.246 + 7.247 + // Check the message obtained. 7.248 + if (errorMsg == null) { 7.249 + throw new RuntimeException("Caught AbstractMethodError with empty message."); 7.250 + } else if (errorMsg.equals(expectedErrorMessageAME3_1)) { 7.251 + // Expected test case thrown via LinkResolver::runtime_resolve_virtual_method(). 7.252 + System.out.println("Passed with message: " + errorMsg); 7.253 + } else { 7.254 + System.out.println("Expected: " + expectedErrorMessageAME3_1 + "\n" + 7.255 + "but got: " + errorMsg); 7.256 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.257 + } 7.258 + } 7.259 + } 7.260 + 7.261 + private static String expectedErrorMessageAME3_2 = 7.262 + "Receiver class AME3_C does not define or inherit an implementation of " + 7.263 + "the resolved method abstract ma()V of abstract class AME3_B."; 7.264 + 7.265 + // Testing abstract class that extends a class that has an implementation. 7.266 + // Loop so that method gets eventually compiled/osred. 7.267 + public static void test_ame3_2() throws Exception { 7.268 + AME3_C c = new AME3_C(); 7.269 + 7.270 + try { 7.271 + // Supposed to throw AME with verbose message. 7.272 + c.ma(); 7.273 + 7.274 + throw new RuntimeException("Expected AbstractMethodError was not thrown."); 7.275 + } catch (AbstractMethodError e) { 7.276 + String errorMsg = e.getMessage(); 7.277 + 7.278 + // Check the message obtained. 7.279 + if (errorMsg == null) { 7.280 + throw new RuntimeException("Caught AbstractMethodError with empty message."); 7.281 + } else if (errorMsg.equals(expectedErrorMessageAME3_2)) { 7.282 + // Expected test case thrown via LinkResolver::runtime_resolve_virtual_method(). 7.283 + System.out.println("Passed with message: " + errorMsg); 7.284 + } else { 7.285 + System.out.println("Expected: " + expectedErrorMessageAME3_2 + "\n" + 7.286 + "but got: " + errorMsg); 7.287 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.288 + } 7.289 + } 7.290 + } 7.291 + 7.292 + private static String expectedErrorMessageAME4 = 7.293 + "Missing implementation of resolved method abstract ma()V of " + 7.294 + "abstract class AME4_B."; 7.295 + 7.296 + // Testing abstract class that extends a class that has an implementation. 7.297 + public static void test_ame4() throws Exception { 7.298 + AME4_C c = new AME4_C(); 7.299 + AME4_D d = new AME4_D(); 7.300 + AME4_E e = new AME4_E(); // Errorneous. 7.301 + 7.302 + AME4_A a; 7.303 + try { 7.304 + // Test: calls errorneous e.ma() in the last iteration. 7.305 + final int iterations = 10; 7.306 + for (int i = 0; i < iterations; i++) { 7.307 + a = e; 7.308 + if (i % 2 == 0 && i < iterations - 1) { 7.309 + a = c; 7.310 + } 7.311 + if (i % 2 == 1 && i < iterations - 1) { 7.312 + a = d; 7.313 + } 7.314 + 7.315 + // AbstractMethodError gets thrown in the interpreter at: 7.316 + // InterpreterGenerator::generate_abstract_entry 7.317 + a.ma(); 7.318 + } 7.319 + 7.320 + throw new RuntimeException("Expected AbstractMethodError was not thrown."); 7.321 + } catch (AbstractMethodError exc) { 7.322 + System.out.println(); 7.323 + String errorMsg = exc.getMessage(); 7.324 + 7.325 + // Check the message obtained. 7.326 + if (enableChecks && errorMsg == null) { 7.327 + throw new RuntimeException("Caught AbstractMethodError with empty message."); 7.328 + } else if (errorMsg.equals(expectedErrorMessageAME4)) { 7.329 + // Expected test case. 7.330 + System.out.println("Passed with message: " + errorMsg); 7.331 + } else if (enableChecks) { 7.332 + System.out.println("Expected: " + expectedErrorMessageAME4 + "\n" + 7.333 + "but got: " + errorMsg); 7.334 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.335 + } 7.336 + } 7.337 + } 7.338 + 7.339 + private static String expectedErrorMessageAME5_VtableStub = 7.340 + "Receiver class AME5_B does not define or inherit an implementation of the resolved method abstract mc()V " + 7.341 + "of abstract class AME5_A."; 7.342 + 7.343 + // AbstractMethodErrors detected in vtable stubs. 7.344 + // Note: How can we verify that we really stepped through the vtable stub? 7.345 + // - Bimorphic inlining should not happen since we have no profiling data when 7.346 + // we compile the method 7.347 + // - As a result, an inline cache call should be generated 7.348 + // - This inline cache call is patched into a real vtable call at the first 7.349 + // re-resolve, which happens constantly during the first 10 iterations of the loop. 7.350 + // => we should be fine! :-) 7.351 + public static void test_ame5_compiled_vtable_stub() { 7.352 + // Allocated the objects we need and call a valid method. 7.353 + boolean caught_ame = false; 7.354 + AME5_B b = new AME5_B(); 7.355 + AME5_C c = new AME5_C(); 7.356 + AME5_D d = new AME5_D(); 7.357 + AME5_E e = new AME5_E(); 7.358 + b.ma(); 7.359 + c.ma(); 7.360 + d.ma(); 7.361 + e.ma(); 7.362 + 7.363 + try { 7.364 + final int iterations = 10; 7.365 + // Test: calls b.c() in the last iteration. 7.366 + for (int i = 0; i < iterations; i++) { 7.367 + AME5_A a = b; 7.368 + if (i % 3 == 0 && i < iterations - 1) { 7.369 + a = c; 7.370 + } 7.371 + if (i % 3 == 1 && i < iterations - 1) { 7.372 + a = d; 7.373 + } 7.374 + if (i % 3 == 2 && i < iterations - 1) { 7.375 + a = e; 7.376 + } 7.377 + 7.378 + a.mc(); 7.379 + } 7.380 + System.out.println(); 7.381 + } catch (AbstractMethodError exc) { 7.382 + caught_ame = true; 7.383 + System.out.println(); 7.384 + String errorMsg = exc.getMessage(); 7.385 + if (enableChecks && errorMsg == null) { 7.386 + System.out.println(exc); 7.387 + throw new RuntimeException("Empty error message of AbstractMethodError."); 7.388 + } 7.389 + if (enableChecks && 7.390 + !errorMsg.equals(expectedErrorMessageAME5_VtableStub)) { 7.391 + // Thrown via SharedRuntime::handle_wrong_method_abstract(). 7.392 + System.out.println("Expected: " + expectedErrorMessageAME5_VtableStub + "\n" + 7.393 + "but got: " + errorMsg); 7.394 + System.out.println(exc); 7.395 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.396 + } 7.397 + if (enableChecks) { 7.398 + System.out.println("Passed with message: " + errorMsg); 7.399 + } 7.400 + } catch (Throwable exc) { 7.401 + 7.402 + throw exc; 7.403 + } 7.404 + 7.405 + // Check that we got the exception at some point. 7.406 + if (enableChecks && !caught_ame) { 7.407 + throw new RuntimeException("Expected AbstractMethodError was not thrown."); 7.408 + } 7.409 + } 7.410 + 7.411 + private static String expectedErrorMessageAME6_ItableStub = 7.412 + "Receiver class AME6_B does not define or inherit an implementation of the resolved" + 7.413 + " method abstract mc()V of interface AME6_A."; 7.414 + 7.415 + // ------------------------------------------------------------------------- 7.416 + // AbstractMethodErrors detected in itable stubs. 7.417 + // Note: How can we verify that we really stepped through the itable stub? 7.418 + // - Bimorphic inlining should not happen since we have no profiling data when 7.419 + // we compile the method 7.420 + // - As a result, an inline cache call should be generated 7.421 + // - This inline cache call is patched into a real vtable call at the first 7.422 + // re-resolve, which happens constantly during the first 10 iterations of the loop. 7.423 + // => we should be fine! :-) 7.424 + public static void test_ame6_compiled_itable_stub() { 7.425 + // Allocated the objects we need and call a valid method. 7.426 + boolean caught_ame = false; 7.427 + AME6_B b = new AME6_B(); 7.428 + AME6_C c = new AME6_C(); 7.429 + AME6_D d = new AME6_D(); 7.430 + AME6_E e = new AME6_E(); 7.431 + b.ma(); 7.432 + c.ma(); 7.433 + d.ma(); 7.434 + e.ma(); 7.435 + 7.436 + try { 7.437 + final int iterations = 10; 7.438 + // Test: calls b.c() in the last iteration. 7.439 + for (int i = 0; i < iterations; i++) { 7.440 + AME6_A a = b; 7.441 + if (i % 3 == 0 && i < iterations - 1) { 7.442 + a = c; 7.443 + } 7.444 + if (i % 3 == 1 && i < iterations - 1) { 7.445 + a = d; 7.446 + } 7.447 + if (i % 3 == 2 && i < iterations - 1) { 7.448 + a = e; 7.449 + } 7.450 + a.mc(); 7.451 + } 7.452 + System.out.println(); 7.453 + } catch (AbstractMethodError exc) { 7.454 + caught_ame = true; 7.455 + System.out.println(); 7.456 + String errorMsg = exc.getMessage(); 7.457 + if (enableChecks && errorMsg == null) { 7.458 + System.out.println(exc); 7.459 + throw new RuntimeException("Empty error message of AbstractMethodError."); 7.460 + } 7.461 + if (enableChecks && 7.462 + !errorMsg.equals(expectedErrorMessageAME6_ItableStub)) { 7.463 + // Thrown via LinkResolver::runtime_resolve_interface_method(). 7.464 + System.out.println("Expected: " + expectedErrorMessageAME6_ItableStub + "\n" + 7.465 + "but got: " + errorMsg); 7.466 + System.out.println(exc); 7.467 + throw new RuntimeException("Wrong error message of AbstractMethodError."); 7.468 + } 7.469 + if (enableChecks) { 7.470 + System.out.println("Passed with message: " + errorMsg); 7.471 + } 7.472 + } catch (Throwable exc) { 7.473 + throw exc; 7.474 + } 7.475 + 7.476 + // Check that we got the exception at some point. 7.477 + if (enableChecks && !caught_ame) { 7.478 + throw new RuntimeException("Expected AbstractMethodError was not thrown."); 7.479 + } 7.480 + } 7.481 + 7.482 + 7.483 + public static void main(String[] args) throws Exception { 7.484 + if (!setup_test()) { 7.485 + return; 7.486 + } 7.487 + test_ame1(); 7.488 + test_ame2(); 7.489 + test_ame3_1(); 7.490 + test_ame3_2(); 7.491 + test_ame4(); 7.492 + test_ame5_compiled_vtable_stub(); 7.493 + test_ame6_compiled_itable_stub(); 7.494 + } 7.495 +} 7.496 + 7.497 +// Helper classes to test abstract method error. 7.498 +// 7.499 +// Errorneous versions of these classes are implemented in java 7.500 +// assembler. 7.501 + 7.502 + 7.503 +// ------------------------------------------------------------------------- 7.504 +// This error should be detected interpreted. 7.505 +// 7.506 +// Class hierachy: 7.507 +// 7.508 +// C // interface, defines aFunctionOfMyInterface() 7.509 +// | 7.510 +// A | // interface 7.511 +// | | 7.512 +// B | // abstract class, defines anAbstractMethod() 7.513 +// \ / 7.514 +// E // errorneous class implementation lacks methods C::aFunctionOfMyInterface() 7.515 +// B::anAbstractMethod() 7.516 +interface AME1_A { 7.517 + 7.518 + public String firstFunctionOfMyInterface0(); 7.519 + 7.520 + public String secondFunctionOfMyInterface0(); 7.521 +} 7.522 + 7.523 +abstract class AME1_B implements AME1_A { 7.524 + 7.525 + abstract public String firstAbstractMethod(); 7.526 + 7.527 + abstract public String secondAbstractMethod(); 7.528 + 7.529 + abstract public String anAbstractMethod(); 7.530 +} 7.531 + 7.532 +interface AME1_C { 7.533 + 7.534 + public String firstFunctionOfMyInterface(); 7.535 + 7.536 + public String secondFunctionOfMyInterface(); 7.537 + 7.538 + public String aFunctionOfMyInterface(); 7.539 +} 7.540 + 7.541 +class AME1_D extends AME1_B implements AME1_C { 7.542 + 7.543 + public AME1_D() { 7.544 + } 7.545 + 7.546 + public String firstAbstractMethod() { 7.547 + return this.getClass().getName(); 7.548 + } 7.549 + 7.550 + public String secondAbstractMethod() { 7.551 + return this.getClass().getName(); 7.552 + } 7.553 + 7.554 + public String anAbstractMethod() { 7.555 + return this.getClass().getName(); 7.556 + } 7.557 + 7.558 + public String firstFunctionOfMyInterface0() { 7.559 + return this.getClass().getName(); 7.560 + } 7.561 + 7.562 + public String secondFunctionOfMyInterface0() { 7.563 + return this.getClass().getName(); 7.564 + } 7.565 + 7.566 + public String firstFunctionOfMyInterface() { 7.567 + return this.getClass().getName(); 7.568 + } 7.569 + 7.570 + public String secondFunctionOfMyInterface() { 7.571 + return this.getClass().getName(); 7.572 + } 7.573 + 7.574 + public String aFunctionOfMyInterface() { 7.575 + return this.getClass().getName(); 7.576 + } 7.577 +} 7.578 + 7.579 +class AME1_E extends AME1_B implements AME1_C { 7.580 + 7.581 + public AME1_E() { 7.582 + } 7.583 + 7.584 + public String firstAbstractMethod() { 7.585 + return this.getClass().getName(); 7.586 + } 7.587 + 7.588 + public String secondAbstractMethod() { 7.589 + return this.getClass().getName(); 7.590 + } 7.591 + 7.592 + // This method is missing in the .jasm implementation. 7.593 + public String anAbstractMethod() { 7.594 + return this.getClass().getName(); 7.595 + } 7.596 + 7.597 + public String firstFunctionOfMyInterface0() { 7.598 + return this.getClass().getName(); 7.599 + } 7.600 + 7.601 + public String secondFunctionOfMyInterface0() { 7.602 + return this.getClass().getName(); 7.603 + } 7.604 + 7.605 + public String firstFunctionOfMyInterface() { 7.606 + return this.getClass().getName(); 7.607 + } 7.608 + 7.609 + public String secondFunctionOfMyInterface() { 7.610 + return this.getClass().getName(); 7.611 + } 7.612 + 7.613 + // This method is missing in the .jasm implementation. 7.614 + public String aFunctionOfMyInterface() { 7.615 + return this.getClass().getName(); 7.616 + } 7.617 +} 7.618 + 7.619 +// ------------------------------------------------------------------------- 7.620 +// This error should be detected interpreted. 7.621 +// 7.622 +// Class hierachy: 7.623 +// 7.624 +// A // an interface declaring aFunctionOfMyInterface() 7.625 +// | 7.626 +// B // an abstract class 7.627 +// | 7.628 +// C // errorneous implementation lacks method A::aFunctionOfMyInterface() 7.629 +// 7.630 +interface AME2_A { 7.631 + public void aFunctionOfMyInterface(); 7.632 +} 7.633 + 7.634 +abstract class AME2_B implements AME2_A { 7.635 + abstract public void fun2(); 7.636 +} 7.637 + 7.638 +class ImplementsAllFunctions extends AME2_B { 7.639 + 7.640 + public ImplementsAllFunctions() {} 7.641 + 7.642 + public void fun2() { 7.643 + //System.out.print("You called public void ImplementsAllFunctions::fun2().\n"); 7.644 + } 7.645 + 7.646 + public void aFunctionOfMyInterface() { 7.647 + //System.out.print("You called public void ImplementsAllFunctions::aFunctionOfMyInterface()\n"); 7.648 + } 7.649 +} 7.650 + 7.651 +class AME2_C extends AME2_B { 7.652 + 7.653 + public AME2_C() {} 7.654 + 7.655 + public void fun2() { 7.656 + //System.out.print("You called public void AME2_C::fun2().\n"); 7.657 + } 7.658 + 7.659 + // This method is missing in the .jasm implementation. 7.660 + public void aFunctionOfMyInterface() { 7.661 + //System.out.print("You called public void AME2_C::aFunctionOfMyInterface()\n"); 7.662 + } 7.663 +} 7.664 + 7.665 +// ----------------------------------------------------------------------- 7.666 +// Test AbstractMethod error shadowing existing implementation. 7.667 +// 7.668 +// Class hierachy: 7.669 +// 7.670 +// A // a class implementing m() 7.671 +// | 7.672 +// B // an abstract class defining m() abstract 7.673 +// | 7.674 +// C // an errorneous class lacking an implementation of m() 7.675 +// 7.676 +class AME3_A { 7.677 + public void ma() { 7.678 + System.out.print("A.ma() "); 7.679 + } 7.680 +} 7.681 + 7.682 +abstract class AME3_B extends AME3_A { 7.683 + public abstract void ma(); 7.684 +} 7.685 + 7.686 +class AME3_C extends AME3_B { 7.687 + // This method is missing in the .jasm implementation. 7.688 + public void ma() { 7.689 + System.out.print("C.ma() "); 7.690 + } 7.691 +} 7.692 + 7.693 +// ----------------------------------------------------------------------- 7.694 +// Test AbstractMethod error shadowing existing implementation. In 7.695 +// this test there are several subclasses of the abstract class. 7.696 +// 7.697 +// Class hierachy: 7.698 +// 7.699 +// A // A: a class implementing ma() 7.700 +// | 7.701 +// B // B: an abstract class defining ma() abstract 7.702 +// / | \ 7.703 +// C D E // E: an errorneous class lacking an implementation of ma() 7.704 +// 7.705 +class AME4_A { 7.706 + public void ma() { 7.707 + System.out.print("A.ma() "); 7.708 + } 7.709 +} 7.710 + 7.711 +abstract class AME4_B extends AME4_A { 7.712 + public abstract void ma(); 7.713 +} 7.714 + 7.715 +class AME4_C extends AME4_B { 7.716 + public void ma() { 7.717 + System.out.print("C.ma() "); 7.718 + } 7.719 +} 7.720 + 7.721 +class AME4_D extends AME4_B { 7.722 + public void ma() { 7.723 + System.out.print("D.ma() "); 7.724 + } 7.725 +} 7.726 + 7.727 +class AME4_E extends AME4_B { 7.728 + // This method is missing in the .jasm implementation. 7.729 + public void ma() { 7.730 + System.out.print("E.ma() "); 7.731 + } 7.732 +} 7.733 + 7.734 +// ------------------------------------------------------------------------- 7.735 +// This error should be detected while processing the vtable stub. 7.736 +// 7.737 +// Class hierachy: 7.738 +// 7.739 +// A__ // abstract 7.740 +// /|\ \ 7.741 +// C D E \ 7.742 +// B // Bad class, missing method implementation. 7.743 +// 7.744 +// Test: 7.745 +// - Call D.mc() / E.mc() / F.mc() several times to force real vtable call constrution 7.746 +// - Call errorneous B.mc() in the end to raise the AbstraceMethodError 7.747 + 7.748 +abstract class AME5_A { 7.749 + public abstract void ma(); 7.750 + public abstract void mb(); 7.751 + public abstract void mc(); 7.752 +} 7.753 + 7.754 +class AME5_B extends AME5_A { 7.755 + public void ma() { 7.756 + System.out.print("B.ma() "); 7.757 + } 7.758 + 7.759 + public void mb() { 7.760 + System.out.print("B.mb() "); 7.761 + } 7.762 + 7.763 + // This method is missing in the .jasm implementation. 7.764 + public void mc() { 7.765 + System.out.print("B.mc() "); 7.766 + } 7.767 +} 7.768 + 7.769 +class AME5_C extends AME5_A { 7.770 + public void ma() { 7.771 + System.out.print("C.ma() "); 7.772 + } 7.773 + 7.774 + public void mb() { 7.775 + System.out.print("C.mb() "); 7.776 + } 7.777 + 7.778 + public void mc() { 7.779 + System.out.print("C.mc() "); 7.780 + } 7.781 +} 7.782 + 7.783 +class AME5_D extends AME5_A { 7.784 + public void ma() { 7.785 + System.out.print("D.ma() "); 7.786 + } 7.787 + 7.788 + public void mb() { 7.789 + System.out.print("D.mb() "); 7.790 + } 7.791 + 7.792 + public void mc() { 7.793 + System.out.print("D.mc() "); 7.794 + } 7.795 +} 7.796 + 7.797 +class AME5_E extends AME5_A { 7.798 + public void ma() { 7.799 + System.out.print("E.ma() "); 7.800 + } 7.801 + 7.802 + public void mb() { 7.803 + System.out.print("E.mb() "); 7.804 + } 7.805 + 7.806 + public void mc() { 7.807 + System.out.print("E.mc() "); 7.808 + } 7.809 +} 7.810 + 7.811 +//------------------------------------------------------------------------- 7.812 +// Test AbstractMethod error detected while processing 7.813 +// the itable stub. 7.814 +// 7.815 +// Class hierachy: 7.816 +// 7.817 +// A__ (interface) 7.818 +// /|\ \ 7.819 +// C D E \ 7.820 +// B (bad class, missing method) 7.821 +// 7.822 +// Test: 7.823 +// - Call D.mc() / E.mc() / F.mc() several times to force real itable call constrution 7.824 +// - Call errorneous B.mc() in the end to raise the AbstraceMethodError 7.825 + 7.826 +interface AME6_A { 7.827 + abstract void ma(); 7.828 + abstract void mb(); 7.829 + abstract void mc(); 7.830 +} 7.831 + 7.832 +class AME6_B implements AME6_A { 7.833 + public void ma() { 7.834 + System.out.print("B.ma() "); 7.835 + } 7.836 + 7.837 + public void mb() { 7.838 + System.out.print("B.mb() "); 7.839 + } 7.840 + 7.841 + // This method is missing in the .jasm implementation. 7.842 + public void mc() { 7.843 + System.out.print("B.mc() "); 7.844 + } 7.845 +} 7.846 + 7.847 +class AME6_C implements AME6_A { 7.848 + public void ma() { 7.849 + System.out.print("C.ma() "); 7.850 + } 7.851 + 7.852 + public void mb() { 7.853 + System.out.print("C.mb() "); 7.854 + } 7.855 + 7.856 + public void mc() { 7.857 + System.out.print("C.mc() "); 7.858 + } 7.859 +} 7.860 + 7.861 +class AME6_D implements AME6_A { 7.862 + public void ma() { 7.863 + System.out.print("D.ma() "); 7.864 + } 7.865 + 7.866 + public void mb() { 7.867 + System.out.print("D.mb() "); 7.868 + } 7.869 + 7.870 + public void mc() { 7.871 + System.out.print("D.mc() "); 7.872 + } 7.873 +} 7.874 + 7.875 +class AME6_E implements AME6_A { 7.876 + public void ma() { 7.877 + System.out.print("E.ma() "); 7.878 + } 7.879 + 7.880 + public void mb() { 7.881 + System.out.print("E.mb() "); 7.882 + } 7.883 + 7.884 + public void mc() { 7.885 + System.out.print("E.mc() "); 7.886 + } 7.887 +}