Thu, 04 Sep 2008 14:56:35 -0700
Merge
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/file/CacheFSInfo.java Thu Sep 04 14:56:35 2008 -0700 1.3 @@ -0,0 +1,122 @@ 1.4 +/* 1.5 + * Copyright 2005-2008 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.javac.file; 1.30 + 1.31 +import java.io.File; 1.32 +import java.io.IOException; 1.33 +import java.util.List; 1.34 + 1.35 +import com.sun.tools.javac.util.Context; 1.36 +import java.util.Map; 1.37 +import java.util.concurrent.ConcurrentHashMap; 1.38 + 1.39 +/** 1.40 + * Caching implementation of FSInfo 1.41 + */ 1.42 +public class CacheFSInfo extends FSInfo { 1.43 + 1.44 + /** 1.45 + * Register a Context.Factory to create a singleton CacheFSInfo. 1.46 + */ 1.47 + public static void preRegister(final Context context) { 1.48 + context.put(FSInfo.class, new Context.Factory<FSInfo>() { 1.49 + public FSInfo make() { 1.50 + if (singleton == null) 1.51 + singleton = new CacheFSInfo(); 1.52 + context.put(FSInfo.class, singleton); 1.53 + return singleton; 1.54 + } 1.55 + }); 1.56 + } 1.57 + 1.58 + static CacheFSInfo singleton; 1.59 + 1.60 + public void clearCache() { 1.61 + cache.clear(); 1.62 + } 1.63 + 1.64 + @Override 1.65 + public File getCanonicalFile(File file) { 1.66 + Entry e = getEntry(file); 1.67 + return e.canonicalFile; 1.68 + } 1.69 + 1.70 + @Override 1.71 + public boolean exists(File file) { 1.72 + Entry e = getEntry(file); 1.73 + return e.exists; 1.74 + } 1.75 + 1.76 + @Override 1.77 + public boolean isDirectory(File file) { 1.78 + Entry e = getEntry(file); 1.79 + return e.isDirectory; 1.80 + } 1.81 + 1.82 + @Override 1.83 + public boolean isFile(File file) { 1.84 + Entry e = getEntry(file); 1.85 + return e.isFile; 1.86 + } 1.87 + 1.88 + @Override 1.89 + public List<File> getJarClassPath(File file) throws IOException { 1.90 + // don't bother to lock the cache, because it is thread-safe, and 1.91 + // because the worst that can happen would be to create two identical 1.92 + // jar class paths together and have one overwrite the other. 1.93 + Entry e = getEntry(file); 1.94 + if (e.jarClassPath == null) 1.95 + e.jarClassPath = super.getJarClassPath(file); 1.96 + return e.jarClassPath; 1.97 + } 1.98 + 1.99 + private Entry getEntry(File file) { 1.100 + // don't bother to lock the cache, because it is thread-safe, and 1.101 + // because the worst that can happen would be to create two identical 1.102 + // entries together and have one overwrite the other. 1.103 + Entry e = cache.get(file); 1.104 + if (e == null) { 1.105 + e = new Entry(); 1.106 + e.canonicalFile = super.getCanonicalFile(file); 1.107 + e.exists = super.exists(file); 1.108 + e.isDirectory = super.isDirectory(file); 1.109 + e.isFile = super.isFile(file); 1.110 + cache.put(file, e); 1.111 + } 1.112 + return e; 1.113 + } 1.114 + 1.115 + // could also be a Map<File,SoftReference<Entry>> ? 1.116 + private Map<File,Entry> cache = new ConcurrentHashMap<File,Entry>(); 1.117 + 1.118 + private static class Entry { 1.119 + File canonicalFile; 1.120 + boolean exists; 1.121 + boolean isFile; 1.122 + boolean isDirectory; 1.123 + List<File> jarClassPath; 1.124 + } 1.125 +}
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/src/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Sep 04 14:56:35 2008 -0700 2.3 @@ -0,0 +1,89 @@ 2.4 + 2.5 +package com.sun.tools.javac.file; 2.6 + 2.7 +import java.io.File; 2.8 +import java.io.IOException; 2.9 +import java.util.ArrayList; 2.10 +import java.util.Collections; 2.11 +import java.util.List; 2.12 +import java.util.StringTokenizer; 2.13 +import java.util.jar.Attributes; 2.14 +import java.util.jar.JarFile; 2.15 +import java.util.jar.Manifest; 2.16 + 2.17 +import com.sun.tools.javac.util.Context; 2.18 + 2.19 +/** 2.20 + * Get meta-info about files. Default direct (non-caching) implementation. 2.21 + * @see CacheFSInfo 2.22 + */ 2.23 +public class FSInfo { 2.24 + 2.25 + /** Get the FSInfo instance for this context. 2.26 + * @param context the context 2.27 + * @return the Paths instance for this context 2.28 + */ 2.29 + public static FSInfo instance(Context context) { 2.30 + FSInfo instance = context.get(FSInfo.class); 2.31 + if (instance == null) 2.32 + instance = new FSInfo(); 2.33 + return instance; 2.34 + } 2.35 + 2.36 + protected FSInfo() { 2.37 + } 2.38 + 2.39 + protected FSInfo(Context context) { 2.40 + context.put(FSInfo.class, this); 2.41 + } 2.42 + 2.43 + public File getCanonicalFile(File file) { 2.44 + try { 2.45 + return file.getCanonicalFile(); 2.46 + } catch (IOException e) { 2.47 + return file.getAbsoluteFile(); 2.48 + } 2.49 + } 2.50 + 2.51 + public boolean exists(File file) { 2.52 + return file.exists(); 2.53 + } 2.54 + 2.55 + public boolean isDirectory(File file) { 2.56 + return file.isDirectory(); 2.57 + } 2.58 + 2.59 + public boolean isFile(File file) { 2.60 + return file.isFile(); 2.61 + } 2.62 + 2.63 + public List<File> getJarClassPath(File file) throws IOException { 2.64 + String parent = file.getParent(); 2.65 + JarFile jarFile = new JarFile(file); 2.66 + try { 2.67 + Manifest man = jarFile.getManifest(); 2.68 + if (man == null) 2.69 + return Collections.emptyList(); 2.70 + 2.71 + Attributes attr = man.getMainAttributes(); 2.72 + if (attr == null) 2.73 + return Collections.emptyList(); 2.74 + 2.75 + String path = attr.getValue(Attributes.Name.CLASS_PATH); 2.76 + if (path == null) 2.77 + return Collections.emptyList(); 2.78 + 2.79 + List<File> list = new ArrayList<File>(); 2.80 + 2.81 + for (StringTokenizer st = new StringTokenizer(path); st.hasMoreTokens(); ) { 2.82 + String elt = st.nextToken(); 2.83 + File f = (parent == null ? new File(elt) : new File(parent, elt)); 2.84 + list.add(f); 2.85 + } 2.86 + 2.87 + return list; 2.88 + } finally { 2.89 + jarFile.close(); 2.90 + } 2.91 + } 2.92 +}
3.1 --- a/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Sun Aug 31 12:00:43 2008 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Sep 04 14:56:35 2008 -0700 3.3 @@ -55,7 +55,6 @@ 3.4 import java.util.Iterator; 3.5 import java.util.Map; 3.6 import java.util.Set; 3.7 -import java.util.concurrent.ConcurrentHashMap; 3.8 import java.util.zip.ZipFile; 3.9 3.10 import javax.lang.model.SourceVersion; 3.11 @@ -88,10 +87,6 @@ 3.12 3.13 boolean useZipFileIndex; 3.14 3.15 - private static boolean CHECK_ZIP_TIMESTAMP = false; 3.16 - private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 3.17 - 3.18 - 3.19 public static char[] toArray(CharBuffer buffer) { 3.20 if (buffer.hasArray()) 3.21 return ((CharBuffer)buffer.compact().flip()).array(); 3.22 @@ -110,6 +105,8 @@ 3.23 3.24 private Options options; 3.25 3.26 + private FSInfo fsInfo; 3.27 + 3.28 private final File uninited = new File("U N I N I T E D"); 3.29 3.30 private final Set<JavaFileObject.Kind> sourceOrClass = 3.31 @@ -172,9 +169,9 @@ 3.32 } 3.33 3.34 options = Options.instance(context); 3.35 + fsInfo = FSInfo.instance(context); 3.36 3.37 useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null; 3.38 - CHECK_ZIP_TIMESTAMP = System.getProperty("checkZipIndexTimestamp") != null;// TODO: options.get("checkZipIndexTimestamp") != null; 3.39 3.40 mmappedIO = options.get("mmappedIO") != null; 3.41 ignoreSymbolFile = options.get("ignore.symbol.file") != null; 3.42 @@ -289,20 +286,7 @@ 3.43 ListBuffer<JavaFileObject> l) { 3.44 Archive archive = archives.get(directory); 3.45 3.46 - boolean isFile = false; 3.47 - if (CHECK_ZIP_TIMESTAMP) { 3.48 - Boolean isf = isDirectory.get(directory); 3.49 - if (isf == null) { 3.50 - isFile = directory.isFile(); 3.51 - isDirectory.put(directory, isFile); 3.52 - } 3.53 - else { 3.54 - isFile = directory.isFile(); 3.55 - } 3.56 - } 3.57 - else { 3.58 - isFile = directory.isFile(); 3.59 - } 3.60 + boolean isFile = fsInfo.isFile(directory); 3.61 3.62 if (archive != null || isFile) { 3.63 if (archive == null) {
4.1 --- a/src/share/classes/com/sun/tools/javac/file/Paths.java Sun Aug 31 12:00:43 2008 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/file/Paths.java Thu Sep 04 14:56:35 2008 -0700 4.3 @@ -31,19 +31,11 @@ 4.4 import java.util.HashSet; 4.5 import java.util.Map; 4.6 import java.util.Set; 4.7 -import java.util.jar.JarFile; 4.8 -import java.util.jar.Manifest; 4.9 -import java.util.jar.Attributes; 4.10 import java.util.Collection; 4.11 import java.util.Collections; 4.12 import java.util.LinkedHashSet; 4.13 import java.util.Iterator; 4.14 -import java.util.StringTokenizer; 4.15 import java.util.zip.ZipFile; 4.16 -import java.util.ArrayList; 4.17 -import java.util.concurrent.ConcurrentHashMap; 4.18 -import java.util.concurrent.locks.Lock; 4.19 -import java.util.concurrent.locks.ReentrantLock; 4.20 import javax.tools.JavaFileManager.Location; 4.21 4.22 import com.sun.tools.javac.code.Lint; 4.23 @@ -90,21 +82,8 @@ 4.24 /** Handler for -Xlint options */ 4.25 private Lint lint; 4.26 4.27 - private static boolean NON_BATCH_MODE = System.getProperty("nonBatchMode") != null;// TODO: Use -XD compiler switch for this. 4.28 - private static Map<File, PathEntry> pathExistanceCache = new ConcurrentHashMap<File, PathEntry>(); 4.29 - private static Map<File, java.util.List<File>> manifestEntries = new ConcurrentHashMap<File, java.util.List<File>>(); 4.30 - private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>(); 4.31 - private static Lock lock = new ReentrantLock(); 4.32 - 4.33 - public static void clearPathExistanceCache() { 4.34 - pathExistanceCache.clear(); 4.35 - } 4.36 - 4.37 - static class PathEntry { 4.38 - boolean exists = false; 4.39 - boolean isFile = false; 4.40 - File cannonicalPath = null; 4.41 - } 4.42 + /** Access to (possibly cached) file info */ 4.43 + private FSInfo fsInfo; 4.44 4.45 protected Paths(Context context) { 4.46 context.put(pathsKey, this); 4.47 @@ -116,6 +95,7 @@ 4.48 log = Log.instance(context); 4.49 options = Options.instance(context); 4.50 lint = Lint.instance(context); 4.51 + fsInfo = FSInfo.instance(context); 4.52 } 4.53 4.54 /** Whether to warn about non-existent path elements */ 4.55 @@ -294,51 +274,17 @@ 4.56 } 4.57 4.58 public void addFile(File file, boolean warn) { 4.59 - boolean foundInCache = false; 4.60 - PathEntry pe = null; 4.61 - if (!NON_BATCH_MODE) { 4.62 - pe = pathExistanceCache.get(file); 4.63 - if (pe != null) { 4.64 - foundInCache = true; 4.65 - } 4.66 - else { 4.67 - pe = new PathEntry(); 4.68 - } 4.69 - } 4.70 - else { 4.71 - pe = new PathEntry(); 4.72 - } 4.73 - 4.74 - File canonFile; 4.75 - try { 4.76 - if (!foundInCache) { 4.77 - pe.cannonicalPath = file.getCanonicalFile(); 4.78 - } 4.79 - else { 4.80 - canonFile = pe.cannonicalPath; 4.81 - } 4.82 - } catch (IOException e) { 4.83 - pe.cannonicalPath = canonFile = file; 4.84 - } 4.85 - 4.86 - if (contains(file) || canonicalValues.contains(pe.cannonicalPath)) { 4.87 + File canonFile = fsInfo.getCanonicalFile(file); 4.88 + if (contains(file) || canonicalValues.contains(canonFile)) { 4.89 /* Discard duplicates and avoid infinite recursion */ 4.90 return; 4.91 } 4.92 4.93 - if (!foundInCache) { 4.94 - pe.exists = file.exists(); 4.95 - pe.isFile = file.isFile(); 4.96 - if (!NON_BATCH_MODE) { 4.97 - pathExistanceCache.put(file, pe); 4.98 - } 4.99 - } 4.100 - 4.101 - if (! pe.exists) { 4.102 + if (! fsInfo.exists(file)) { 4.103 /* No such file or directory exists */ 4.104 if (warn) 4.105 log.warning("path.element.not.found", file); 4.106 - } else if (pe.isFile) { 4.107 + } else if (fsInfo.isFile(file)) { 4.108 /* File is an ordinary file. */ 4.109 if (!isArchive(file)) { 4.110 /* Not a recognized extension; open it to see if 4.111 @@ -360,9 +306,9 @@ 4.112 /* Now what we have left is either a directory or a file name 4.113 confirming to archive naming convention */ 4.114 super.add(file); 4.115 - canonicalValues.add(pe.cannonicalPath); 4.116 + canonicalValues.add(canonFile); 4.117 4.118 - if (expandJarClassPaths && file.exists() && file.isFile()) 4.119 + if (expandJarClassPaths && fsInfo.exists(file) && fsInfo.isFile(file)) 4.120 addJarClassPath(file, warn); 4.121 } 4.122 4.123 @@ -372,58 +318,8 @@ 4.124 // filenames, but if we do, we should redo all path-related code. 4.125 private void addJarClassPath(File jarFile, boolean warn) { 4.126 try { 4.127 - java.util.List<File> manifestsList = manifestEntries.get(jarFile); 4.128 - if (!NON_BATCH_MODE) { 4.129 - lock.lock(); 4.130 - try { 4.131 - if (manifestsList != null) { 4.132 - for (File entr : manifestsList) { 4.133 - addFile(entr, warn); 4.134 - } 4.135 - return; 4.136 - } 4.137 - } 4.138 - finally { 4.139 - lock.unlock(); 4.140 - } 4.141 - } 4.142 - 4.143 - if (!NON_BATCH_MODE) { 4.144 - manifestsList = new ArrayList<File>(); 4.145 - manifestEntries.put(jarFile, manifestsList); 4.146 - } 4.147 - 4.148 - String jarParent = jarFile.getParent(); 4.149 - JarFile jar = new JarFile(jarFile); 4.150 - 4.151 - try { 4.152 - Manifest man = jar.getManifest(); 4.153 - if (man == null) return; 4.154 - 4.155 - Attributes attr = man.getMainAttributes(); 4.156 - if (attr == null) return; 4.157 - 4.158 - String path = attr.getValue(Attributes.Name.CLASS_PATH); 4.159 - if (path == null) return; 4.160 - 4.161 - for (StringTokenizer st = new StringTokenizer(path); 4.162 - st.hasMoreTokens();) { 4.163 - String elt = st.nextToken(); 4.164 - File f = (jarParent == null ? new File(elt) : new File(jarParent, elt)); 4.165 - addFile(f, warn); 4.166 - 4.167 - if (!NON_BATCH_MODE) { 4.168 - lock.lock(); 4.169 - try { 4.170 - manifestsList.add(f); 4.171 - } 4.172 - finally { 4.173 - lock.unlock(); 4.174 - } 4.175 - } 4.176 - } 4.177 - } finally { 4.178 - jar.close(); 4.179 + for (File f: fsInfo.getJarClassPath(jarFile)) { 4.180 + addFile(f, warn); 4.181 } 4.182 } catch (IOException e) { 4.183 log.error("error.reading.file", jarFile, e.getLocalizedMessage()); 4.184 @@ -554,24 +450,9 @@ 4.185 } 4.186 4.187 /** Is this the name of an archive file? */ 4.188 - private static boolean isArchive(File file) { 4.189 + private boolean isArchive(File file) { 4.190 String n = file.getName().toLowerCase(); 4.191 - boolean isFile = false; 4.192 - if (!NON_BATCH_MODE) { 4.193 - Boolean isf = isDirectory.get(file); 4.194 - if (isf == null) { 4.195 - isFile = file.isFile(); 4.196 - isDirectory.put(file, isFile); 4.197 - } 4.198 - else { 4.199 - isFile = isf; 4.200 - } 4.201 - } 4.202 - else { 4.203 - isFile = file.isFile(); 4.204 - } 4.205 - 4.206 - return isFile 4.207 + return fsInfo.isFile(file) 4.208 && (n.endsWith(".jar") || n.endsWith(".zip")); 4.209 } 4.210 }
5.1 --- a/src/share/classes/com/sun/tools/javac/main/Main.java Sun Aug 31 12:00:43 2008 -0700 5.2 +++ b/src/share/classes/com/sun/tools/javac/main/Main.java Thu Sep 04 14:56:35 2008 -0700 5.3 @@ -31,6 +31,7 @@ 5.4 import java.util.MissingResourceException; 5.5 5.6 import com.sun.tools.javac.code.Source; 5.7 +import com.sun.tools.javac.file.CacheFSInfo; 5.8 import com.sun.tools.javac.file.JavacFileManager; 5.9 import com.sun.tools.javac.jvm.Target; 5.10 import com.sun.tools.javac.main.JavacOption.Option; 5.11 @@ -368,6 +369,12 @@ 5.12 5.13 context.put(Log.outKey, out); 5.14 5.15 + // allow System property in following line as a Mustang legacy 5.16 + boolean batchMode = (options.get("nonBatchMode") == null 5.17 + && System.getProperty("nonBatchMode") == null); 5.18 + if (batchMode) 5.19 + CacheFSInfo.preRegister(context); 5.20 + 5.21 fileManager = context.get(JavaFileManager.class); 5.22 5.23 comp = JavaCompiler.instance(context);