T7093325.java revision 1519:5c956be64b9e
1/* 2 * Copyright (c) 2011, 2013, 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 * @test 26 * @bug 7093325 8006694 27 * @summary Redundant entry in bytecode exception table 28 * temporarily workaround combo tests are causing time out in several platforms 29 * @library lib 30 * @build JavacTestingAbstractThreadedTest 31 * @run main/othervm T7093325 32 */ 33 34// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047) 35// see JDK-8006746 36 37import java.io.File; 38import java.net.URI; 39import java.util.Arrays; 40import javax.tools.JavaCompiler; 41import javax.tools.JavaFileObject; 42import javax.tools.SimpleJavaFileObject; 43import javax.tools.ToolProvider; 44 45import com.sun.source.util.JavacTask; 46import com.sun.tools.classfile.Attribute; 47import com.sun.tools.classfile.ClassFile; 48import com.sun.tools.classfile.Code_attribute; 49import com.sun.tools.classfile.ConstantPool.*; 50import com.sun.tools.classfile.Method; 51 52public class T7093325 53 extends JavacTestingAbstractThreadedTest 54 implements Runnable { 55 56 enum StatementKind { 57 THROW("throw new RuntimeException();", false, false), 58 RETURN_NONEMPTY("System.out.println(); return;", true, false), 59 RETURN_EMPTY("return;", true, true), 60 APPLY("System.out.println();", true, false); 61 62 String stmt; 63 boolean canInline; 64 boolean empty; 65 66 private StatementKind(String stmt, boolean canInline, boolean empty) { 67 this.stmt = stmt; 68 this.canInline = canInline; 69 this.empty = empty; 70 } 71 } 72 73 enum CatchArity { 74 NONE(""), 75 ONE("catch (A a) { #S1 }"), 76 TWO("catch (B b) { #S2 }"), 77 THREE("catch (C c) { #S3 }"), 78 FOUR("catch (D d) { #S4 }"); 79 80 String catchStr; 81 82 private CatchArity(String catchStr) { 83 this.catchStr = catchStr; 84 } 85 86 String catchers() { 87 if (this.ordinal() == 0) { 88 return catchStr; 89 } else { 90 return CatchArity.values()[this.ordinal() - 1].catchers() + 91 catchStr; 92 } 93 } 94 } 95 96 public static void main(String... args) throws Exception { 97 for (CatchArity ca : CatchArity.values()) { 98 for (StatementKind stmt0 : StatementKind.values()) { 99 if (ca.ordinal() == 0) { 100 pool.execute(new T7093325(ca, stmt0)); 101 continue; 102 } 103 for (StatementKind stmt1 : StatementKind.values()) { 104 if (ca.ordinal() == 1) { 105 pool.execute(new T7093325(ca, stmt0, stmt1)); 106 continue; 107 } 108 for (StatementKind stmt2 : StatementKind.values()) { 109 if (ca.ordinal() == 2) { 110 pool.execute(new T7093325(ca, stmt0, stmt1, stmt2)); 111 continue; 112 } 113 for (StatementKind stmt3 : StatementKind.values()) { 114 if (ca.ordinal() == 3) { 115 pool.execute( 116 new T7093325(ca, stmt0, stmt1, stmt2, stmt3)); 117 continue; 118 } 119 for (StatementKind stmt4 : StatementKind.values()) { 120 if (ca.ordinal() == 4) { 121 pool.execute( 122 new T7093325(ca, stmt0, stmt1, 123 stmt2, stmt3, stmt4)); 124 continue; 125 } 126 for (StatementKind stmt5 : StatementKind.values()) { 127 pool.execute( 128 new T7093325(ca, stmt0, stmt1, stmt2, 129 stmt3, stmt4, stmt5)); 130 } 131 } 132 } 133 } 134 } 135 } 136 } 137 138 checkAfterExec(); 139 } 140 141 /** instance decls **/ 142 143 CatchArity ca; 144 StatementKind[] stmts; 145 146 public T7093325(CatchArity ca, StatementKind... stmts) { 147 this.ca = ca; 148 this.stmts = stmts; 149 } 150 151 @Override 152 public void run() { 153 int id = checkCount.incrementAndGet(); 154 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); 155 JavaSource source = new JavaSource(id); 156 JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), null, 157 null, null, Arrays.asList(source)); 158 ct.call(); 159 verifyBytecode(source, id); 160 } 161 162 void verifyBytecode(JavaSource source, int id) { 163 boolean lastInlined = false; 164 boolean hasCode = false; 165 int gapsCount = 0; 166 for (int i = 0; i < stmts.length ; i++) { 167 lastInlined = stmts[i].canInline; 168 hasCode = hasCode || !stmts[i].empty; 169 if (lastInlined && hasCode) { 170 hasCode = false; 171 gapsCount++; 172 } 173 } 174 if (!lastInlined) { 175 gapsCount++; 176 } 177 178 File compiledTest = new File(String.format("Test%s.class", id)); 179 try { 180 ClassFile cf = ClassFile.read(compiledTest); 181 if (cf == null) { 182 throw new Error("Classfile not found: " + 183 compiledTest.getName()); 184 } 185 186 Method test_method = null; 187 for (Method m : cf.methods) { 188 if (m.getName(cf.constant_pool).equals("test")) { 189 test_method = m; 190 break; 191 } 192 } 193 194 if (test_method == null) { 195 throw new Error("Method test() not found in class Test"); 196 } 197 198 Code_attribute code = null; 199 for (Attribute a : test_method.attributes) { 200 if (a.getName(cf.constant_pool).equals(Attribute.Code)) { 201 code = (Code_attribute)a; 202 break; 203 } 204 } 205 206 if (code == null) { 207 throw new Error("Code attribute not found in method test()"); 208 } 209 210 int actualGapsCount = 0; 211 for (int i = 0; i < code.exception_table_langth ; i++) { 212 int catchType = code.exception_table[i].catch_type; 213 if (catchType == 0) { //any 214 actualGapsCount++; 215 } 216 } 217 218 if (actualGapsCount != gapsCount) { 219 throw new Error("Bad exception table for test()\n" + 220 "expected gaps: " + gapsCount + "\n" + 221 "found gaps: " + actualGapsCount + "\n" + 222 source); 223 } 224 } catch (Exception e) { 225 e.printStackTrace(); 226 throw new Error("error reading " + compiledTest +": " + e); 227 } 228 229 } 230 231 class JavaSource extends SimpleJavaFileObject { 232 233 static final String source_template = 234 "class A extends RuntimeException {} \n" + 235 "class B extends RuntimeException {} \n" + 236 "class C extends RuntimeException {} \n" + 237 "class D extends RuntimeException {} \n" + 238 "class E extends RuntimeException {} \n" + 239 "class Test#ID {\n" + 240 " void test() {\n" + 241 " try { #S0 } #C finally { System.out.println(); }\n" + 242 " }\n" + 243 "}"; 244 245 String source; 246 247 public JavaSource(int id) { 248 super(URI.create(String.format("myfo:/Test%s.java", id)), 249 JavaFileObject.Kind.SOURCE); 250 source = source_template.replace("#C", ca.catchers()); 251 source = source.replace("#S0", stmts[0].stmt); 252 source = source.replace("#ID", String.valueOf(id)); 253 for (int i = 1; i < ca.ordinal() + 1; i++) { 254 source = source.replace("#S" + i, stmts[i].stmt); 255 } 256 } 257 258 @Override 259 public String toString() { 260 return source; 261 } 262 263 @Override 264 public CharSequence getCharContent(boolean ignoreEncodingErrors) { 265 return source; 266 } 267 } 268 269} 270