test/langtools/tools/javac/T7093325.java
changeset 47216 71c04702a3d5
parent 32454 b0ac04e0fefe
child 47350 d65c3b21081c
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 2011, 2015, 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 8129962
       
    27  * @summary Redundant entry in bytecode exception table
       
    28  *  temporarily workaround combo tests are causing time out in several platforms
       
    29  * @library /tools/javac/lib
       
    30  * @modules jdk.jdeps/com.sun.tools.classfile
       
    31  *          jdk.compiler/com.sun.tools.javac.api
       
    32  *          jdk.compiler/com.sun.tools.javac.code
       
    33  *          jdk.compiler/com.sun.tools.javac.comp
       
    34  *          jdk.compiler/com.sun.tools.javac.main
       
    35  *          jdk.compiler/com.sun.tools.javac.tree
       
    36  *          jdk.compiler/com.sun.tools.javac.util
       
    37  * @build combo.ComboTestHelper
       
    38  * @run main T7093325
       
    39  */
       
    40 
       
    41 import java.io.IOException;
       
    42 import java.io.InputStream;
       
    43 
       
    44 import com.sun.tools.classfile.Attribute;
       
    45 import com.sun.tools.classfile.ClassFile;
       
    46 import com.sun.tools.classfile.Code_attribute;
       
    47 import com.sun.tools.classfile.ConstantPoolException;
       
    48 import com.sun.tools.classfile.Method;
       
    49 
       
    50 import javax.tools.JavaFileObject;
       
    51 
       
    52 import combo.ComboInstance;
       
    53 import combo.ComboParameter;
       
    54 import combo.ComboTask.Result;
       
    55 import combo.ComboTestHelper;
       
    56 
       
    57 public class T7093325 extends ComboInstance<T7093325> {
       
    58 
       
    59     enum StatementKind implements ComboParameter {
       
    60         NONE(null, false, false),
       
    61         THROW("throw new RuntimeException();", false, false),
       
    62         RETURN_NONEMPTY("System.out.println(); return;", true, false),
       
    63         RETURN_EMPTY("return;", true, true),
       
    64         APPLY("System.out.println();", true, false);
       
    65 
       
    66         String stmt;
       
    67         boolean canInline;
       
    68         boolean empty;
       
    69 
       
    70         StatementKind(String stmt, boolean canInline, boolean empty) {
       
    71             this.stmt = stmt;
       
    72             this.canInline = canInline;
       
    73             this.empty = empty;
       
    74         }
       
    75 
       
    76         @Override
       
    77         public String expand(String optParameter) {
       
    78             return stmt;
       
    79         }
       
    80     }
       
    81 
       
    82     enum CatchArity implements ComboParameter {
       
    83         NONE(""),
       
    84         ONE("catch (A a) { #{STMT[1]} }"),
       
    85         TWO("catch (B b) { #{STMT[2]} }"),
       
    86         THREE("catch (C c) { #{STMT[3]} }"),
       
    87         FOUR("catch (D d) { #{STMT[4]} }");
       
    88 
       
    89         String catchStr;
       
    90 
       
    91         CatchArity(String catchStr) {
       
    92             this.catchStr = catchStr;
       
    93         }
       
    94 
       
    95         @Override
       
    96         public String expand(String optParameter) {
       
    97             if (this.ordinal() == 0) {
       
    98                 return catchStr;
       
    99             } else {
       
   100                 return CatchArity.values()[this.ordinal() - 1].expand(optParameter) +
       
   101                         catchStr;
       
   102             }
       
   103         }
       
   104     }
       
   105 
       
   106     public static void main(String... args) throws Exception {
       
   107         new ComboTestHelper<T7093325>()
       
   108                 .withFilter(T7093325::testFilter)
       
   109                 .withDimension("CATCH", (x, ca) -> x.ca = ca, CatchArity.values())
       
   110                 .withArrayDimension("STMT", (x, stmt, idx) -> x.stmts[idx] = stmt, 5, StatementKind.values())
       
   111                 .run(T7093325::new);
       
   112     }
       
   113 
       
   114     /** instance decls **/
       
   115 
       
   116     CatchArity ca;
       
   117     StatementKind[] stmts = new StatementKind[5];
       
   118 
       
   119     boolean testFilter() {
       
   120         int lastPos = ca.ordinal() + 1;
       
   121         for (int i = 0; i < stmts.length ; i++) {
       
   122             boolean shouldBeSet = i < lastPos;
       
   123             boolean isSet = stmts[i] != StatementKind.NONE;
       
   124             if (shouldBeSet != isSet) {
       
   125                 return false;
       
   126             }
       
   127         }
       
   128         return true;
       
   129     }
       
   130 
       
   131     @Override
       
   132     public void doWork() throws IOException {
       
   133         verifyBytecode(newCompilationTask()
       
   134                 .withSourceFromTemplate(source_template)
       
   135                 .generate());
       
   136     }
       
   137 
       
   138     void verifyBytecode(Result<Iterable<? extends JavaFileObject>> result) {
       
   139         boolean lastInlined = false;
       
   140         boolean hasCode = false;
       
   141         int gapsCount = 0;
       
   142         for (int i = 0; i < ca.ordinal() + 1 ; i++) {
       
   143             lastInlined = stmts[i].canInline;
       
   144             hasCode = hasCode || !stmts[i].empty;
       
   145             if (lastInlined && hasCode) {
       
   146                 hasCode = false;
       
   147                 gapsCount++;
       
   148             }
       
   149         }
       
   150         if (!lastInlined) {
       
   151             gapsCount++;
       
   152         }
       
   153 
       
   154         try (InputStream is = result.get().iterator().next().openInputStream()) {
       
   155             ClassFile cf = ClassFile.read(is);
       
   156             if (cf == null) {
       
   157                 fail("Classfile not found: " + result.compilationInfo());
       
   158                 return;
       
   159             }
       
   160 
       
   161             Method test_method = null;
       
   162             for (Method m : cf.methods) {
       
   163                 if (m.getName(cf.constant_pool).equals("test")) {
       
   164                     test_method = m;
       
   165                     break;
       
   166                 }
       
   167             }
       
   168 
       
   169             if (test_method == null) {
       
   170                 fail("Method test() not found in class Test" + result.compilationInfo());
       
   171                 return;
       
   172             }
       
   173 
       
   174             Code_attribute code = null;
       
   175             for (Attribute a : test_method.attributes) {
       
   176                 if (a.getName(cf.constant_pool).equals(Attribute.Code)) {
       
   177                     code = (Code_attribute)a;
       
   178                     break;
       
   179                 }
       
   180             }
       
   181 
       
   182             if (code == null) {
       
   183                 fail("Code attribute not found in method test()");
       
   184                 return;
       
   185             }
       
   186 
       
   187             int actualGapsCount = 0;
       
   188             for (int i = 0; i < code.exception_table_length ; i++) {
       
   189                 int catchType = code.exception_table[i].catch_type;
       
   190                 if (catchType == 0) { //any
       
   191                     actualGapsCount++;
       
   192                 }
       
   193             }
       
   194 
       
   195             if (actualGapsCount != gapsCount) {
       
   196                 fail("Bad exception table for test()\n" +
       
   197                             "expected gaps: " + gapsCount + "\n" +
       
   198                             "found gaps: " + actualGapsCount + "\n" +
       
   199                         result.compilationInfo());
       
   200                 return;
       
   201             }
       
   202         } catch (IOException | ConstantPoolException e) {
       
   203             e.printStackTrace();
       
   204             fail("error reading classfile: " + e);
       
   205         }
       
   206 
       
   207     }
       
   208 
       
   209     static final String source_template =
       
   210                 "class Test {\n" +
       
   211                 "   void test() {\n" +
       
   212                 "   try { #{STMT[0]} } #{CATCH} finally { System.out.println(); }\n" +
       
   213                 "   }\n" +
       
   214                 "}\n" +
       
   215                 "class A extends RuntimeException {} \n" +
       
   216                 "class B extends RuntimeException {} \n" +
       
   217                 "class C extends RuntimeException {} \n" +
       
   218                 "class D extends RuntimeException {} \n" +
       
   219                 "class E extends RuntimeException {}";
       
   220 }