Tue, 04 Jun 2013 14:17:50 -0700
8004643: Reduce javac space overhead introduced with compiler support for repeating annotations
Reviewed-by: mcimadamore, jfranck
jjg@1569 | 1 | /* |
jjg@1569 | 2 | * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. |
jjg@1569 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
jjg@1569 | 4 | * |
jjg@1569 | 5 | * This code is free software; you can redistribute it and/or modify it |
jjg@1569 | 6 | * under the terms of the GNU General Public License version 2 only, as |
jjg@1569 | 7 | * published by the Free Software Foundation. Oracle designates this |
jjg@1569 | 8 | * particular file as subject to the "Classpath" exception as provided |
jjg@1569 | 9 | * by Oracle in the LICENSE file that accompanied this code. |
jjg@1569 | 10 | * |
jjg@1569 | 11 | * This code is distributed in the hope that it will be useful, but WITHOUT |
jjg@1569 | 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
jjg@1569 | 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
jjg@1569 | 14 | * version 2 for more details (a copy is included in the LICENSE file that |
jjg@1569 | 15 | * accompanied this code). |
jjg@1569 | 16 | * |
jjg@1569 | 17 | * You should have received a copy of the GNU General Public License version |
jjg@1569 | 18 | * 2 along with this work; if not, write to the Free Software Foundation, |
jjg@1569 | 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
jjg@1569 | 20 | * |
jjg@1569 | 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
jjg@1569 | 22 | * or visit www.oracle.com if you need additional information or have any |
jjg@1569 | 23 | * questions. |
jjg@1569 | 24 | */ |
jjg@1569 | 25 | package com.sun.tools.javac.sym; |
jjg@1569 | 26 | |
jjg@1569 | 27 | import java.io.BufferedInputStream; |
jjg@1569 | 28 | import java.io.BufferedWriter; |
jjg@1569 | 29 | import java.io.File; |
jjg@1569 | 30 | import java.io.FileInputStream; |
jjg@1569 | 31 | import java.io.FileWriter; |
jjg@1569 | 32 | import java.io.IOException; |
jjg@1569 | 33 | import java.nio.charset.Charset; |
jjg@1569 | 34 | import java.nio.file.Files; |
jjg@1569 | 35 | import java.util.HashMap; |
jjg@1569 | 36 | import java.util.Map; |
jjg@1569 | 37 | import java.util.Properties; |
jjg@1569 | 38 | import java.util.Set; |
jjg@1569 | 39 | import java.util.TreeMap; |
jjg@1569 | 40 | import java.util.TreeSet; |
jjg@1569 | 41 | |
jjg@1569 | 42 | import com.sun.tools.javac.util.Assert; |
jjg@1569 | 43 | |
jjg@1569 | 44 | /** |
jjg@1569 | 45 | * Provide details about profile contents. |
jjg@1569 | 46 | * |
jjg@1569 | 47 | * <p><b>This is NOT part of any supported API. |
jjg@1569 | 48 | * If you write code that depends on this, you do so at your own |
jjg@1569 | 49 | * risk. This code and its internal interfaces are subject to change |
jjg@1569 | 50 | * or deletion without notice.</b></p> |
jjg@1569 | 51 | */ |
jjg@1569 | 52 | public abstract class Profiles { |
jjg@1569 | 53 | // for debugging |
jjg@1569 | 54 | public static void main(String[] args) throws IOException { |
jjg@1569 | 55 | Profiles p = Profiles.read(new File(args[0])); |
jjg@1569 | 56 | if (args.length >= 2) { |
jjg@1569 | 57 | Map<Integer,Set<String>> lists = new TreeMap<Integer,Set<String>>(); |
jjg@1569 | 58 | for (int i = 1; i <= 4; i++) |
jjg@1569 | 59 | lists.put(i, new TreeSet<String>()); |
jjg@1569 | 60 | |
jjg@1569 | 61 | File rt_jar_lst = new File(args[1]); |
jjg@1569 | 62 | for (String line: Files.readAllLines(rt_jar_lst.toPath(), Charset.defaultCharset())) { |
jjg@1569 | 63 | if (line.endsWith(".class")) { |
jjg@1569 | 64 | String type = line.substring(0, line.length() - 6); |
jjg@1569 | 65 | int profile = p.getProfile(type); |
jjg@1569 | 66 | for (int i = profile; i <= 4; i++) |
jjg@1569 | 67 | lists.get(i).add(type); |
jjg@1569 | 68 | } |
jjg@1569 | 69 | } |
jjg@1569 | 70 | |
jjg@1569 | 71 | for (int i = 1; i <= 4; i++) { |
jjg@1569 | 72 | BufferedWriter out = new BufferedWriter(new FileWriter(i + ".txt")); |
jjg@1569 | 73 | try { |
jjg@1569 | 74 | for (String type: lists.get(i)) { |
jjg@1569 | 75 | out.write(type); |
jjg@1569 | 76 | out.newLine(); |
jjg@1569 | 77 | } |
jjg@1569 | 78 | } finally { |
jjg@1569 | 79 | out.close(); |
jjg@1569 | 80 | } |
jjg@1569 | 81 | } |
jjg@1569 | 82 | } |
jjg@1569 | 83 | } |
jjg@1569 | 84 | |
jjg@1569 | 85 | public static Profiles read(File file) throws IOException { |
jjg@1569 | 86 | BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); |
jjg@1569 | 87 | try { |
jjg@1569 | 88 | Properties p = new Properties(); |
jjg@1569 | 89 | p.load(in); |
jjg@1569 | 90 | if (p.containsKey("java/lang/Object")) |
jjg@1569 | 91 | return new SimpleProfiles(p); |
jjg@1569 | 92 | else |
jjg@1569 | 93 | return new MakefileProfiles(p); |
jjg@1569 | 94 | } finally { |
jjg@1569 | 95 | in.close(); |
jjg@1569 | 96 | } |
jjg@1569 | 97 | } |
jjg@1569 | 98 | |
jjg@1569 | 99 | public abstract int getProfileCount(); |
jjg@1569 | 100 | |
jjg@1569 | 101 | public abstract int getProfile(String typeName); |
jjg@1569 | 102 | |
jjg@1569 | 103 | public abstract Set<String> getPackages(int profile); |
jjg@1569 | 104 | |
jjg@1569 | 105 | private static class MakefileProfiles extends Profiles { |
jjg@1569 | 106 | static class Package { |
jjg@1569 | 107 | final Package parent; |
jjg@1569 | 108 | final String name; |
jjg@1569 | 109 | |
jjg@1569 | 110 | Map<String, Package> subpackages = new TreeMap<String, Package>(); |
jjg@1569 | 111 | |
jjg@1569 | 112 | int profile; |
jjg@1569 | 113 | Map<String, Integer> includedTypes = new TreeMap<String,Integer>(); |
jjg@1569 | 114 | Map<String, Integer> excludedTypes = new TreeMap<String,Integer>(); |
jjg@1569 | 115 | |
jjg@1569 | 116 | Package(Package parent, String name) { |
jjg@1569 | 117 | this.parent = parent; |
jjg@1569 | 118 | this.name = name; |
jjg@1569 | 119 | } |
jjg@1569 | 120 | |
jjg@1569 | 121 | int getProfile() { |
jjg@1569 | 122 | return (parent == null) ? profile : Math.max(parent.getProfile(), profile); |
jjg@1569 | 123 | } |
jjg@1569 | 124 | |
jjg@1569 | 125 | int getProfile(String simpleTypeName) { |
jjg@1569 | 126 | Integer i; |
jjg@1569 | 127 | if ((i = includedTypes.get(simpleTypeName)) != null) |
jjg@1569 | 128 | return i; |
jjg@1569 | 129 | if ((i = includedTypes.get("*")) != null) |
jjg@1569 | 130 | return i; |
jjg@1569 | 131 | if ((i = excludedTypes.get(simpleTypeName)) != null) |
jjg@1569 | 132 | return i + 1; |
jjg@1569 | 133 | if ((i = excludedTypes.get("*")) != null) |
jjg@1569 | 134 | return i + 1; |
jjg@1569 | 135 | return getProfile(); |
jjg@1569 | 136 | } |
jjg@1569 | 137 | |
jjg@1569 | 138 | String getName() { |
jjg@1569 | 139 | return (parent == null) ? name : (parent.getName() + "/" + name); |
jjg@1569 | 140 | } |
jjg@1569 | 141 | |
jjg@1569 | 142 | void getPackages(int profile, Set<String> results) { |
jjg@1569 | 143 | int prf = getProfile(); |
jjg@1569 | 144 | if (prf != 0 && profile >= prf) |
jjg@1569 | 145 | results.add(getName()); |
jjg@1569 | 146 | for (Package pkg: subpackages.values()) |
jjg@1569 | 147 | pkg.getPackages(profile, results); |
jjg@1569 | 148 | } |
jjg@1569 | 149 | } |
jjg@1569 | 150 | |
jjg@1569 | 151 | final static Map<String, Package> packages = new TreeMap<String, Package>(); |
dholmes@1636 | 152 | |
dholmes@1636 | 153 | final int maxProfile = 4; // Three compact profiles plus full JRE |
jjg@1569 | 154 | |
jjg@1569 | 155 | MakefileProfiles(Properties p) { |
dholmes@1636 | 156 | for (int profile = 1; profile <= maxProfile; profile++) { |
dholmes@1636 | 157 | String prefix = (profile < maxProfile ? "PROFILE_" + profile : "FULL_JRE"); |
dholmes@1636 | 158 | String inclPackages = p.getProperty(prefix + "_RTJAR_INCLUDE_PACKAGES"); |
jjg@1569 | 159 | if (inclPackages == null) |
jjg@1569 | 160 | break; |
jjg@1569 | 161 | for (String pkg: inclPackages.substring(1).trim().split("\\s+")) { |
jjg@1569 | 162 | if (pkg.endsWith("/")) |
jjg@1569 | 163 | pkg = pkg.substring(0, pkg.length() - 1); |
jjg@1569 | 164 | includePackage(profile, pkg); |
jjg@1569 | 165 | } |
dholmes@1636 | 166 | String inclTypes = p.getProperty(prefix + "_RTJAR_INCLUDE_TYPES"); |
jjg@1569 | 167 | if (inclTypes != null) { |
jjg@1569 | 168 | for (String type: inclTypes.replace("$$", "$").split("\\s+")) { |
jjg@1569 | 169 | if (type.endsWith(".class")) |
jjg@1569 | 170 | includeType(profile, type.substring(0, type.length() - 6)); |
jjg@1569 | 171 | } |
jjg@1569 | 172 | } |
dholmes@1636 | 173 | String exclTypes = p.getProperty(prefix + "_RTJAR_EXCLUDE_TYPES"); |
jjg@1569 | 174 | if (exclTypes != null) { |
jjg@1569 | 175 | for (String type: exclTypes.replace("$$", "$").split("\\s+")) { |
jjg@1569 | 176 | if (type.endsWith(".class")) |
jjg@1569 | 177 | excludeType(profile, type.substring(0, type.length() - 6)); |
jjg@1569 | 178 | } |
jjg@1569 | 179 | } |
jjg@1569 | 180 | } |
jjg@1569 | 181 | } |
jjg@1569 | 182 | |
jjg@1569 | 183 | @Override |
jjg@1569 | 184 | public int getProfileCount() { |
jjg@1569 | 185 | return maxProfile; |
jjg@1569 | 186 | } |
jjg@1569 | 187 | |
jjg@1569 | 188 | @Override |
jjg@1569 | 189 | public int getProfile(String typeName) { |
jjg@1569 | 190 | int sep = typeName.lastIndexOf("/"); |
jjg@1569 | 191 | String packageName = typeName.substring(0, sep); |
jjg@1569 | 192 | String simpleName = typeName.substring(sep + 1); |
jjg@1569 | 193 | |
jjg@1569 | 194 | Package p = getPackage(packageName); |
jjg@1569 | 195 | return p.getProfile(simpleName); |
jjg@1569 | 196 | } |
jjg@1569 | 197 | |
jjg@1569 | 198 | @Override |
jjg@1569 | 199 | public Set<String> getPackages(int profile) { |
jjg@1569 | 200 | Set<String> results = new TreeSet<String>(); |
jjg@1569 | 201 | for (Package p: packages.values()) |
jjg@1569 | 202 | p.getPackages(profile, results); |
jjg@1569 | 203 | return results; |
jjg@1569 | 204 | } |
jjg@1569 | 205 | |
jjg@1569 | 206 | private void includePackage(int profile, String packageName) { |
jjg@1569 | 207 | // System.err.println("include package " + packageName); |
jjg@1569 | 208 | Package p = getPackage(packageName); |
jjg@1569 | 209 | Assert.check(p.profile == 0); |
jjg@1569 | 210 | p.profile = profile; |
jjg@1569 | 211 | } |
jjg@1569 | 212 | |
jjg@1569 | 213 | private void includeType(int profile, String typeName) { |
jjg@1569 | 214 | // System.err.println("include type " + typeName); |
jjg@1569 | 215 | int sep = typeName.lastIndexOf("/"); |
jjg@1569 | 216 | String packageName = typeName.substring(0, sep); |
jjg@1569 | 217 | String simpleName = typeName.substring(sep + 1); |
jjg@1569 | 218 | |
jjg@1569 | 219 | Package p = getPackage(packageName); |
jjg@1569 | 220 | Assert.check(!p.includedTypes.containsKey(simpleName)); |
jjg@1569 | 221 | p.includedTypes.put(simpleName, profile); |
jjg@1569 | 222 | } |
jjg@1569 | 223 | |
jjg@1569 | 224 | private void excludeType(int profile, String typeName) { |
jjg@1569 | 225 | // System.err.println("exclude type " + typeName); |
jjg@1569 | 226 | int sep = typeName.lastIndexOf("/"); |
jjg@1569 | 227 | String packageName = typeName.substring(0, sep); |
jjg@1569 | 228 | String simpleName = typeName.substring(sep + 1); |
jjg@1569 | 229 | |
jjg@1569 | 230 | Package p = getPackage(packageName); |
jjg@1569 | 231 | Assert.check(!p.excludedTypes.containsKey(simpleName)); |
jjg@1569 | 232 | p.excludedTypes.put(simpleName, profile); |
jjg@1569 | 233 | } |
jjg@1569 | 234 | |
jjg@1569 | 235 | private Package getPackage(String packageName) { |
jjg@1569 | 236 | int sep = packageName.lastIndexOf("/"); |
jjg@1569 | 237 | Package parent; |
jjg@1569 | 238 | Map<String, Package> parentSubpackages; |
jjg@1569 | 239 | String simpleName; |
jjg@1569 | 240 | if (sep == -1) { |
jjg@1569 | 241 | parent = null; |
jjg@1569 | 242 | parentSubpackages = packages; |
jjg@1569 | 243 | simpleName = packageName; |
jjg@1569 | 244 | } else { |
jjg@1569 | 245 | parent = getPackage(packageName.substring(0, sep)); |
jjg@1569 | 246 | parentSubpackages = parent.subpackages; |
jjg@1569 | 247 | simpleName = packageName.substring(sep + 1); |
jjg@1569 | 248 | } |
jjg@1569 | 249 | |
jjg@1569 | 250 | Package p = parentSubpackages.get(simpleName); |
jjg@1569 | 251 | if (p == null) { |
jjg@1569 | 252 | parentSubpackages.put(simpleName, p = new Package(parent, simpleName)); |
jjg@1569 | 253 | } |
jjg@1569 | 254 | return p; |
jjg@1569 | 255 | } |
jjg@1569 | 256 | } |
jjg@1569 | 257 | |
jjg@1569 | 258 | private static class SimpleProfiles extends Profiles { |
jjg@1569 | 259 | private final Map<String, Integer> map; |
jjg@1569 | 260 | private final int profileCount; |
jjg@1569 | 261 | |
jjg@1569 | 262 | SimpleProfiles(Properties p) { |
jjg@1569 | 263 | int max = 0; |
jjg@1569 | 264 | map = new HashMap<String, Integer>(); |
jjg@1569 | 265 | for (Map.Entry<Object,Object> e: p.entrySet()) { |
jjg@1569 | 266 | String typeName = (String) e.getKey(); |
jjg@1569 | 267 | int profile = Integer.valueOf((String) e.getValue()); |
jjg@1569 | 268 | map.put(typeName, profile); |
jjg@1569 | 269 | max = Math.max(max, profile); |
jjg@1569 | 270 | } |
jjg@1569 | 271 | profileCount = max; |
jjg@1569 | 272 | } |
jjg@1569 | 273 | |
jjg@1569 | 274 | @Override |
jjg@1569 | 275 | public int getProfileCount() { |
jjg@1569 | 276 | return profileCount; |
jjg@1569 | 277 | } |
jjg@1569 | 278 | |
jjg@1569 | 279 | @Override |
jjg@1569 | 280 | public int getProfile(String typeName) { |
jjg@1569 | 281 | return map.get(typeName); |
jjg@1569 | 282 | } |
jjg@1569 | 283 | |
jjg@1569 | 284 | @Override |
jjg@1569 | 285 | public Set<String> getPackages(int profile) { |
jjg@1569 | 286 | Set<String> results = new TreeSet<String>(); |
jjg@1569 | 287 | for (Map.Entry<String,Integer> e: map.entrySet()) { |
jjg@1569 | 288 | String tn = e.getKey(); |
jjg@1569 | 289 | int prf = e.getValue(); |
jjg@1569 | 290 | int sep = tn.lastIndexOf("/"); |
jjg@1569 | 291 | if (sep > 0 && profile >= prf) |
jjg@1569 | 292 | results.add(tn); |
jjg@1569 | 293 | } |
jjg@1569 | 294 | return results; |
jjg@1569 | 295 | } |
jjg@1569 | 296 | } |
jjg@1569 | 297 | } |