Thu, 30 Jul 2009 10:29:53 +0100
6827648: Extremely slow compilation time for visitor pattern code + generics
Summary: Javac unnecessarily recomputates type-substitutions multiple times
Reviewed-by: jjg
jjg@103 | 1 | /* |
jjg@103 | 2 | * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. |
jjg@103 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
jjg@103 | 4 | * |
jjg@103 | 5 | * This code is free software; you can redistribute it and/or modify it |
jjg@103 | 6 | * under the terms of the GNU General Public License version 2 only, as |
jjg@103 | 7 | * published by the Free Software Foundation. |
jjg@103 | 8 | * |
jjg@103 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
jjg@103 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
jjg@103 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
jjg@103 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
jjg@103 | 13 | * accompanied this code). |
jjg@103 | 14 | * |
jjg@103 | 15 | * You should have received a copy of the GNU General Public License version |
jjg@103 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
jjg@103 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
jjg@103 | 18 | * |
jjg@103 | 19 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
jjg@103 | 20 | * CA 95054 USA or visit www.sun.com if you need additional information or |
jjg@103 | 21 | * have any questions. |
jjg@103 | 22 | */ |
jjg@103 | 23 | |
jjg@103 | 24 | /* |
jjg@103 | 25 | * @test |
jjg@103 | 26 | * @bug 6508981 |
jjg@103 | 27 | * @summary cleanup file separator handling in JavacFileManager |
jjg@103 | 28 | * (This test is specifically to test the new impl of inferBinaryName) |
jjg@103 | 29 | * @build p.A |
jjg@103 | 30 | * @run main TestInferBinaryName |
jjg@103 | 31 | */ |
jjg@103 | 32 | |
jjg@103 | 33 | import java.io.*; |
jjg@103 | 34 | import java.util.*; |
jjg@103 | 35 | import javax.tools.*; |
jjg@103 | 36 | |
jjg@103 | 37 | import com.sun.tools.javac.file.JavacFileManager; |
jjg@103 | 38 | import com.sun.tools.javac.util.Context; |
jjg@103 | 39 | import com.sun.tools.javac.util.Options; |
jjg@103 | 40 | |
jjg@103 | 41 | import static javax.tools.JavaFileObject.Kind.*; |
jjg@103 | 42 | import static javax.tools.StandardLocation.*; |
jjg@103 | 43 | |
jjg@103 | 44 | |
jjg@103 | 45 | /** |
jjg@103 | 46 | * Verify the various implementations of inferBinaryName, but configuring |
jjg@103 | 47 | * different instances of a file manager, getting a file object, and checking |
jjg@103 | 48 | * the impl of inferBinaryName for that file object. |
jjg@103 | 49 | */ |
jjg@103 | 50 | public class TestInferBinaryName { |
jjg@103 | 51 | static final boolean IGNORE_SYMBOL_FILE = false; |
jjg@103 | 52 | static final boolean USE_SYMBOL_FILE = true; |
jjg@103 | 53 | static final boolean DONT_USE_ZIP_FILE_INDEX = false; |
jjg@103 | 54 | static final boolean USE_ZIP_FILE_INDEX = true; |
jjg@103 | 55 | |
jjg@103 | 56 | public static void main(String... args) throws Exception { |
jjg@103 | 57 | new TestInferBinaryName().run(); |
jjg@103 | 58 | } |
jjg@103 | 59 | |
jjg@103 | 60 | void run() throws Exception { |
jjg@103 | 61 | //System.err.println(System.getProperties()); |
jjg@103 | 62 | testDirectory(); |
jjg@103 | 63 | testSymbolArchive(); |
jjg@103 | 64 | testZipArchive(); |
jjg@103 | 65 | testZipFileIndexArchive(); |
jjg@103 | 66 | testZipFileIndexArchive2(); |
jjg@103 | 67 | if (errors > 0) |
jjg@103 | 68 | throw new Exception(errors + " error found"); |
jjg@103 | 69 | } |
jjg@103 | 70 | |
jjg@103 | 71 | void testDirectory() throws IOException { |
jjg@103 | 72 | String testClassName = "p.A"; |
jjg@103 | 73 | JavaFileManager fm = |
jjg@103 | 74 | getFileManager("test.classes", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX); |
jjg@103 | 75 | test("testDirectory", |
jjg@103 | 76 | fm, testClassName, "com.sun.tools.javac.file.RegularFileObject"); |
jjg@103 | 77 | } |
jjg@103 | 78 | |
jjg@103 | 79 | void testSymbolArchive() throws IOException { |
jjg@103 | 80 | String testClassName = "java.lang.String"; |
jjg@103 | 81 | JavaFileManager fm = |
jjg@103 | 82 | getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX); |
jjg@103 | 83 | test("testSymbolArchive", |
jjg@103 | 84 | fm, testClassName, "com.sun.tools.javac.file.SymbolArchive$SymbolFileObject"); |
jjg@103 | 85 | } |
jjg@103 | 86 | |
jjg@103 | 87 | void testZipArchive() throws IOException { |
jjg@103 | 88 | String testClassName = "java.lang.String"; |
jjg@103 | 89 | JavaFileManager fm = |
jjg@103 | 90 | getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, DONT_USE_ZIP_FILE_INDEX); |
jjg@103 | 91 | test("testZipArchive", |
jjg@103 | 92 | fm, testClassName, "com.sun.tools.javac.file.ZipArchive$ZipFileObject"); |
jjg@103 | 93 | } |
jjg@103 | 94 | |
jjg@103 | 95 | void testZipFileIndexArchive() throws IOException { |
jjg@103 | 96 | String testClassName = "java.lang.String"; |
jjg@103 | 97 | JavaFileManager fm = |
jjg@103 | 98 | getFileManager("sun.boot.class.path", USE_SYMBOL_FILE, USE_ZIP_FILE_INDEX); |
jjg@103 | 99 | test("testZipFileIndexArchive", |
jjg@103 | 100 | fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject"); |
jjg@103 | 101 | } |
jjg@103 | 102 | |
jjg@103 | 103 | void testZipFileIndexArchive2() throws IOException { |
jjg@103 | 104 | String testClassName = "java.lang.String"; |
jjg@103 | 105 | JavaFileManager fm = |
jjg@103 | 106 | getFileManager("sun.boot.class.path", IGNORE_SYMBOL_FILE, USE_ZIP_FILE_INDEX); |
jjg@103 | 107 | test("testZipFileIndexArchive2", |
jjg@103 | 108 | fm, testClassName, "com.sun.tools.javac.file.ZipFileIndexArchive$ZipFileIndexFileObject"); |
jjg@103 | 109 | } |
jjg@103 | 110 | |
jjg@103 | 111 | /** |
jjg@103 | 112 | * @param testName for debugging |
jjg@103 | 113 | * @param fm suitably configured file manager |
jjg@103 | 114 | * @param testClassName the classname to test |
jjg@103 | 115 | * @param implClassName the expected classname of the JavaFileObject impl, |
jjg@103 | 116 | * used for checking that we are checking the expected impl of |
jjg@103 | 117 | * inferBinaryName |
jjg@103 | 118 | */ |
jjg@103 | 119 | void test(String testName, |
jjg@103 | 120 | JavaFileManager fm, String testClassName, String implClassName) throws IOException { |
jjg@103 | 121 | JavaFileObject fo = fm.getJavaFileForInput(CLASS_PATH, testClassName, CLASS); |
jjg@103 | 122 | if (fo == null) { |
jjg@103 | 123 | System.err.println("Can't find " + testClassName); |
jjg@103 | 124 | errors++; |
jjg@103 | 125 | return; |
jjg@103 | 126 | } |
jjg@103 | 127 | |
jjg@103 | 128 | String cn = fo.getClass().getName(); |
jjg@103 | 129 | String bn = fm.inferBinaryName(CLASS_PATH, fo); |
jjg@103 | 130 | System.err.println(testName + " " + cn + " " + bn); |
jjg@103 | 131 | check(cn, implClassName); |
jjg@103 | 132 | check(bn, testClassName); |
jjg@103 | 133 | System.err.println("OK"); |
jjg@103 | 134 | } |
jjg@103 | 135 | |
jjg@103 | 136 | JavaFileManager getFileManager(String classpathProperty, |
jjg@103 | 137 | boolean symFileKind, |
jjg@103 | 138 | boolean zipFileIndexKind) |
jjg@103 | 139 | throws IOException { |
jjg@103 | 140 | Context ctx = new Context(); |
jjg@103 | 141 | // uugh, ugly back door, should be cleaned up, someday |
jjg@103 | 142 | if (zipFileIndexKind == USE_ZIP_FILE_INDEX) |
jjg@103 | 143 | System.clearProperty("useJavaUtilZip"); |
jjg@103 | 144 | else |
jjg@103 | 145 | System.setProperty("useJavaUtilZip", "true"); |
jjg@103 | 146 | Options options = Options.instance(ctx); |
jjg@103 | 147 | if (symFileKind == IGNORE_SYMBOL_FILE) |
jjg@103 | 148 | options.put("ignore.symbol.file", "true"); |
jjg@103 | 149 | JavacFileManager fm = new JavacFileManager(ctx, false, null); |
jjg@103 | 150 | List<File> path = getPath(System.getProperty(classpathProperty)); |
jjg@103 | 151 | fm.setLocation(CLASS_PATH, path); |
jjg@103 | 152 | return fm; |
jjg@103 | 153 | } |
jjg@103 | 154 | |
jjg@103 | 155 | List<File> getPath(String s) { |
jjg@103 | 156 | List<File> path = new ArrayList<File>(); |
jjg@103 | 157 | for (String f: s.split(File.pathSeparator)) { |
jjg@103 | 158 | if (f.length() > 0) |
jjg@103 | 159 | path.add(new File(f)); |
jjg@103 | 160 | } |
jjg@103 | 161 | //System.err.println("path: " + path); |
jjg@103 | 162 | return path; |
jjg@103 | 163 | } |
jjg@103 | 164 | |
jjg@103 | 165 | void check(String found, String expect) { |
jjg@103 | 166 | if (!found.equals(expect)) { |
jjg@103 | 167 | System.err.println("Expected: " + expect); |
jjg@103 | 168 | System.err.println(" Found: " + found); |
jjg@103 | 169 | errors++; |
jjg@103 | 170 | } |
jjg@103 | 171 | } |
jjg@103 | 172 | |
jjg@103 | 173 | private int errors; |
jjg@103 | 174 | } |
jjg@103 | 175 | |
jjg@103 | 176 | class A { } |
jjg@103 | 177 |