Merge

Thu, 04 Sep 2008 14:56:35 -0700

author
tbell
date
Thu, 04 Sep 2008 14:56:35 -0700
changeset 107
5a9b808557b6
parent 105
7b59e34898ff
parent 106
ceaa6549687a
child 108
258af9b67b7c
child 110
91eea580fbe9

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);

mercurial