Mon, 08 Apr 2013 15:53:08 +0100
8010404: Lambda debugging: redundant LineNumberTable entry for lambda capture
Summary: Ignore indy entries in LineNumberTable
Reviewed-by: jjg
mcimadamore@1109 | 1 | /* |
vromero@1482 | 2 | * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. |
mcimadamore@1109 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
mcimadamore@1109 | 4 | * |
mcimadamore@1109 | 5 | * This code is free software; you can redistribute it and/or modify it |
mcimadamore@1109 | 6 | * under the terms of the GNU General Public License version 2 only, as |
mcimadamore@1109 | 7 | * published by the Free Software Foundation. |
mcimadamore@1109 | 8 | * |
mcimadamore@1109 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
mcimadamore@1109 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
mcimadamore@1109 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
mcimadamore@1109 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
mcimadamore@1109 | 13 | * accompanied this code). |
mcimadamore@1109 | 14 | * |
mcimadamore@1109 | 15 | * You should have received a copy of the GNU General Public License version |
mcimadamore@1109 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
mcimadamore@1109 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
mcimadamore@1109 | 18 | * |
mcimadamore@1109 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
mcimadamore@1109 | 20 | * or visit www.oracle.com if you need additional information or have any |
mcimadamore@1109 | 21 | * questions. |
mcimadamore@1109 | 22 | */ |
mcimadamore@1109 | 23 | |
mcimadamore@1109 | 24 | /* |
mcimadamore@1109 | 25 | * @test |
vromero@1520 | 26 | * @bug 7093325 8006694 |
mcimadamore@1109 | 27 | * @summary Redundant entry in bytecode exception table |
vromero@1520 | 28 | * temporarily workaround combo tests are causing time out in several platforms |
vromero@1482 | 29 | * @library lib |
vromero@1482 | 30 | * @build JavacTestingAbstractThreadedTest |
vromero@1520 | 31 | * @run main/othervm T7093325 |
mcimadamore@1109 | 32 | */ |
mcimadamore@1109 | 33 | |
vromero@1520 | 34 | // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047) |
vromero@1520 | 35 | // see JDK-8006746 |
vromero@1520 | 36 | |
vromero@1482 | 37 | import java.io.File; |
vromero@1482 | 38 | import java.net.URI; |
vromero@1482 | 39 | import java.util.Arrays; |
vromero@1482 | 40 | import javax.tools.JavaCompiler; |
vromero@1482 | 41 | import javax.tools.JavaFileObject; |
vromero@1482 | 42 | import javax.tools.SimpleJavaFileObject; |
vromero@1482 | 43 | import javax.tools.ToolProvider; |
vromero@1482 | 44 | |
mcimadamore@1109 | 45 | import com.sun.source.util.JavacTask; |
mcimadamore@1109 | 46 | import com.sun.tools.classfile.Attribute; |
mcimadamore@1109 | 47 | import com.sun.tools.classfile.ClassFile; |
mcimadamore@1109 | 48 | import com.sun.tools.classfile.Code_attribute; |
mcimadamore@1109 | 49 | import com.sun.tools.classfile.ConstantPool.*; |
mcimadamore@1109 | 50 | import com.sun.tools.classfile.Method; |
mcimadamore@1109 | 51 | |
vromero@1482 | 52 | public class T7093325 |
vromero@1482 | 53 | extends JavacTestingAbstractThreadedTest |
vromero@1482 | 54 | implements Runnable { |
mcimadamore@1109 | 55 | |
mcimadamore@1109 | 56 | enum StatementKind { |
mcimadamore@1109 | 57 | THROW("throw new RuntimeException();", false, false), |
mcimadamore@1109 | 58 | RETURN_NONEMPTY("System.out.println(); return;", true, false), |
mcimadamore@1109 | 59 | RETURN_EMPTY("return;", true, true), |
mcimadamore@1109 | 60 | APPLY("System.out.println();", true, false); |
mcimadamore@1109 | 61 | |
mcimadamore@1109 | 62 | String stmt; |
mcimadamore@1109 | 63 | boolean canInline; |
mcimadamore@1109 | 64 | boolean empty; |
mcimadamore@1109 | 65 | |
mcimadamore@1109 | 66 | private StatementKind(String stmt, boolean canInline, boolean empty) { |
mcimadamore@1109 | 67 | this.stmt = stmt; |
mcimadamore@1109 | 68 | this.canInline = canInline; |
mcimadamore@1109 | 69 | this.empty = empty; |
mcimadamore@1109 | 70 | } |
mcimadamore@1109 | 71 | } |
mcimadamore@1109 | 72 | |
mcimadamore@1109 | 73 | enum CatchArity { |
mcimadamore@1109 | 74 | NONE(""), |
mcimadamore@1109 | 75 | ONE("catch (A a) { #S1 }"), |
mcimadamore@1109 | 76 | TWO("catch (B b) { #S2 }"), |
mcimadamore@1109 | 77 | THREE("catch (C c) { #S3 }"), |
mcimadamore@1109 | 78 | FOUR("catch (D d) { #S4 }"); |
mcimadamore@1109 | 79 | |
mcimadamore@1109 | 80 | String catchStr; |
mcimadamore@1109 | 81 | |
mcimadamore@1109 | 82 | private CatchArity(String catchStr) { |
mcimadamore@1109 | 83 | this.catchStr = catchStr; |
mcimadamore@1109 | 84 | } |
mcimadamore@1109 | 85 | |
mcimadamore@1109 | 86 | String catchers() { |
mcimadamore@1109 | 87 | if (this.ordinal() == 0) { |
mcimadamore@1109 | 88 | return catchStr; |
mcimadamore@1109 | 89 | } else { |
vromero@1482 | 90 | return CatchArity.values()[this.ordinal() - 1].catchers() + |
vromero@1482 | 91 | catchStr; |
mcimadamore@1109 | 92 | } |
mcimadamore@1109 | 93 | } |
mcimadamore@1109 | 94 | } |
mcimadamore@1109 | 95 | |
mcimadamore@1109 | 96 | public static void main(String... args) throws Exception { |
mcimadamore@1109 | 97 | for (CatchArity ca : CatchArity.values()) { |
mcimadamore@1109 | 98 | for (StatementKind stmt0 : StatementKind.values()) { |
mcimadamore@1109 | 99 | if (ca.ordinal() == 0) { |
vromero@1482 | 100 | pool.execute(new T7093325(ca, stmt0)); |
mcimadamore@1109 | 101 | continue; |
mcimadamore@1109 | 102 | } |
mcimadamore@1109 | 103 | for (StatementKind stmt1 : StatementKind.values()) { |
mcimadamore@1109 | 104 | if (ca.ordinal() == 1) { |
vromero@1482 | 105 | pool.execute(new T7093325(ca, stmt0, stmt1)); |
mcimadamore@1109 | 106 | continue; |
mcimadamore@1109 | 107 | } |
mcimadamore@1109 | 108 | for (StatementKind stmt2 : StatementKind.values()) { |
mcimadamore@1109 | 109 | if (ca.ordinal() == 2) { |
vromero@1482 | 110 | pool.execute(new T7093325(ca, stmt0, stmt1, stmt2)); |
mcimadamore@1109 | 111 | continue; |
mcimadamore@1109 | 112 | } |
mcimadamore@1109 | 113 | for (StatementKind stmt3 : StatementKind.values()) { |
mcimadamore@1109 | 114 | if (ca.ordinal() == 3) { |
vromero@1482 | 115 | pool.execute( |
vromero@1482 | 116 | new T7093325(ca, stmt0, stmt1, stmt2, stmt3)); |
mcimadamore@1109 | 117 | continue; |
mcimadamore@1109 | 118 | } |
mcimadamore@1109 | 119 | for (StatementKind stmt4 : StatementKind.values()) { |
mcimadamore@1109 | 120 | if (ca.ordinal() == 4) { |
vromero@1482 | 121 | pool.execute( |
vromero@1482 | 122 | new T7093325(ca, stmt0, stmt1, |
vromero@1482 | 123 | stmt2, stmt3, stmt4)); |
mcimadamore@1109 | 124 | continue; |
mcimadamore@1109 | 125 | } |
mcimadamore@1109 | 126 | for (StatementKind stmt5 : StatementKind.values()) { |
vromero@1482 | 127 | pool.execute( |
vromero@1482 | 128 | new T7093325(ca, stmt0, stmt1, stmt2, |
vromero@1482 | 129 | stmt3, stmt4, stmt5)); |
mcimadamore@1109 | 130 | } |
mcimadamore@1109 | 131 | } |
mcimadamore@1109 | 132 | } |
mcimadamore@1109 | 133 | } |
mcimadamore@1109 | 134 | } |
mcimadamore@1109 | 135 | } |
mcimadamore@1109 | 136 | } |
mcimadamore@1109 | 137 | |
vromero@1482 | 138 | checkAfterExec(); |
mcimadamore@1109 | 139 | } |
mcimadamore@1109 | 140 | |
mcimadamore@1109 | 141 | /** instance decls **/ |
mcimadamore@1109 | 142 | |
mcimadamore@1109 | 143 | CatchArity ca; |
mcimadamore@1109 | 144 | StatementKind[] stmts; |
mcimadamore@1109 | 145 | |
mcimadamore@1109 | 146 | public T7093325(CatchArity ca, StatementKind... stmts) { |
mcimadamore@1109 | 147 | this.ca = ca; |
mcimadamore@1109 | 148 | this.stmts = stmts; |
mcimadamore@1109 | 149 | } |
mcimadamore@1109 | 150 | |
vromero@1482 | 151 | @Override |
vromero@1482 | 152 | public void run() { |
vromero@1482 | 153 | int id = checkCount.incrementAndGet(); |
mcimadamore@1109 | 154 | final JavaCompiler tool = ToolProvider.getSystemJavaCompiler(); |
vromero@1482 | 155 | JavaSource source = new JavaSource(id); |
vromero@1482 | 156 | JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), null, |
mcimadamore@1109 | 157 | null, null, Arrays.asList(source)); |
mcimadamore@1109 | 158 | ct.call(); |
vromero@1482 | 159 | verifyBytecode(source, id); |
mcimadamore@1109 | 160 | } |
mcimadamore@1109 | 161 | |
vromero@1482 | 162 | void verifyBytecode(JavaSource source, int id) { |
mcimadamore@1109 | 163 | boolean lastInlined = false; |
mcimadamore@1109 | 164 | boolean hasCode = false; |
mcimadamore@1109 | 165 | int gapsCount = 0; |
mcimadamore@1109 | 166 | for (int i = 0; i < stmts.length ; i++) { |
mcimadamore@1109 | 167 | lastInlined = stmts[i].canInline; |
mcimadamore@1109 | 168 | hasCode = hasCode || !stmts[i].empty; |
mcimadamore@1109 | 169 | if (lastInlined && hasCode) { |
mcimadamore@1109 | 170 | hasCode = false; |
mcimadamore@1109 | 171 | gapsCount++; |
mcimadamore@1109 | 172 | } |
mcimadamore@1109 | 173 | } |
mcimadamore@1109 | 174 | if (!lastInlined) { |
mcimadamore@1109 | 175 | gapsCount++; |
mcimadamore@1109 | 176 | } |
mcimadamore@1109 | 177 | |
vromero@1482 | 178 | File compiledTest = new File(String.format("Test%s.class", id)); |
mcimadamore@1109 | 179 | try { |
mcimadamore@1109 | 180 | ClassFile cf = ClassFile.read(compiledTest); |
mcimadamore@1109 | 181 | if (cf == null) { |
vromero@1482 | 182 | throw new Error("Classfile not found: " + |
vromero@1482 | 183 | compiledTest.getName()); |
mcimadamore@1109 | 184 | } |
mcimadamore@1109 | 185 | |
mcimadamore@1109 | 186 | Method test_method = null; |
mcimadamore@1109 | 187 | for (Method m : cf.methods) { |
mcimadamore@1109 | 188 | if (m.getName(cf.constant_pool).equals("test")) { |
mcimadamore@1109 | 189 | test_method = m; |
mcimadamore@1109 | 190 | break; |
mcimadamore@1109 | 191 | } |
mcimadamore@1109 | 192 | } |
mcimadamore@1109 | 193 | |
mcimadamore@1109 | 194 | if (test_method == null) { |
mcimadamore@1109 | 195 | throw new Error("Method test() not found in class Test"); |
mcimadamore@1109 | 196 | } |
mcimadamore@1109 | 197 | |
mcimadamore@1109 | 198 | Code_attribute code = null; |
mcimadamore@1109 | 199 | for (Attribute a : test_method.attributes) { |
mcimadamore@1109 | 200 | if (a.getName(cf.constant_pool).equals(Attribute.Code)) { |
mcimadamore@1109 | 201 | code = (Code_attribute)a; |
mcimadamore@1109 | 202 | break; |
mcimadamore@1109 | 203 | } |
mcimadamore@1109 | 204 | } |
mcimadamore@1109 | 205 | |
mcimadamore@1109 | 206 | if (code == null) { |
mcimadamore@1109 | 207 | throw new Error("Code attribute not found in method test()"); |
mcimadamore@1109 | 208 | } |
mcimadamore@1109 | 209 | |
mcimadamore@1109 | 210 | int actualGapsCount = 0; |
mcimadamore@1109 | 211 | for (int i = 0; i < code.exception_table_langth ; i++) { |
mcimadamore@1109 | 212 | int catchType = code.exception_table[i].catch_type; |
mcimadamore@1109 | 213 | if (catchType == 0) { //any |
mcimadamore@1109 | 214 | actualGapsCount++; |
mcimadamore@1109 | 215 | } |
mcimadamore@1109 | 216 | } |
mcimadamore@1109 | 217 | |
mcimadamore@1109 | 218 | if (actualGapsCount != gapsCount) { |
mcimadamore@1109 | 219 | throw new Error("Bad exception table for test()\n" + |
mcimadamore@1109 | 220 | "expected gaps: " + gapsCount + "\n" + |
mcimadamore@1109 | 221 | "found gaps: " + actualGapsCount + "\n" + |
mcimadamore@1109 | 222 | source); |
mcimadamore@1109 | 223 | } |
mcimadamore@1109 | 224 | } catch (Exception e) { |
mcimadamore@1109 | 225 | e.printStackTrace(); |
mcimadamore@1109 | 226 | throw new Error("error reading " + compiledTest +": " + e); |
mcimadamore@1109 | 227 | } |
mcimadamore@1109 | 228 | |
mcimadamore@1109 | 229 | } |
mcimadamore@1109 | 230 | |
mcimadamore@1109 | 231 | class JavaSource extends SimpleJavaFileObject { |
mcimadamore@1109 | 232 | |
mcimadamore@1109 | 233 | static final String source_template = |
mcimadamore@1109 | 234 | "class A extends RuntimeException {} \n" + |
mcimadamore@1109 | 235 | "class B extends RuntimeException {} \n" + |
mcimadamore@1109 | 236 | "class C extends RuntimeException {} \n" + |
mcimadamore@1109 | 237 | "class D extends RuntimeException {} \n" + |
mcimadamore@1109 | 238 | "class E extends RuntimeException {} \n" + |
vromero@1482 | 239 | "class Test#ID {\n" + |
mcimadamore@1109 | 240 | " void test() {\n" + |
mcimadamore@1109 | 241 | " try { #S0 } #C finally { System.out.println(); }\n" + |
mcimadamore@1109 | 242 | " }\n" + |
mcimadamore@1109 | 243 | "}"; |
mcimadamore@1109 | 244 | |
mcimadamore@1109 | 245 | String source; |
mcimadamore@1109 | 246 | |
vromero@1482 | 247 | public JavaSource(int id) { |
vromero@1482 | 248 | super(URI.create(String.format("myfo:/Test%s.java", id)), |
vromero@1482 | 249 | JavaFileObject.Kind.SOURCE); |
mcimadamore@1109 | 250 | source = source_template.replace("#C", ca.catchers()); |
mcimadamore@1109 | 251 | source = source.replace("#S0", stmts[0].stmt); |
vromero@1482 | 252 | source = source.replace("#ID", String.valueOf(id)); |
mcimadamore@1109 | 253 | for (int i = 1; i < ca.ordinal() + 1; i++) { |
mcimadamore@1109 | 254 | source = source.replace("#S" + i, stmts[i].stmt); |
mcimadamore@1109 | 255 | } |
mcimadamore@1109 | 256 | } |
mcimadamore@1109 | 257 | |
mcimadamore@1109 | 258 | @Override |
mcimadamore@1109 | 259 | public String toString() { |
mcimadamore@1109 | 260 | return source; |
mcimadamore@1109 | 261 | } |
mcimadamore@1109 | 262 | |
mcimadamore@1109 | 263 | @Override |
mcimadamore@1109 | 264 | public CharSequence getCharContent(boolean ignoreEncodingErrors) { |
mcimadamore@1109 | 265 | return source; |
mcimadamore@1109 | 266 | } |
mcimadamore@1109 | 267 | } |
vromero@1482 | 268 | |
mcimadamore@1109 | 269 | } |