6724551: Use Queues instead of Lists to link compiler phases
authorjjg
Thu, 10 Jul 2008 16:50:38 -0700
changeset 864 b1cf6afb8244
parent 863 3113c955a388
child 865 21668f049d28
6724551: Use Queues instead of Lists to link compiler phases Reviewed-by: darcy
langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java
langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java
langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java
langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Thu Jul 10 11:25:23 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Thu Jul 10 16:50:38 2008 -0700
@@ -381,8 +381,8 @@
         return results;
     }
     // where
-        private void handleFlowResults(List<Env<AttrContext>> list, ListBuffer<Element> elems) {
-            for (Env<AttrContext> env: list) {
+        private void handleFlowResults(Queue<Env<AttrContext>> queue, ListBuffer<Element> elems) {
+            for (Env<AttrContext> env: queue) {
                 switch (env.tree.getTag()) {
                     case JCTree.CLASSDEF:
                         JCClassDecl cdef = (JCClassDecl) env.tree;
@@ -396,7 +396,7 @@
                         break;
                 }
             }
-            genList.appendList(list);
+            genList.addAll(queue);
         }
 
 
@@ -424,13 +424,13 @@
             analyze(null);  // ensure all classes have been parsed, entered, and analyzed
 
             if (classes == null) {
-                compiler.generate(compiler.desugar(genList.toList()), results);
+                compiler.generate(compiler.desugar(genList), results);
                 genList.clear();
             }
             else {
                 Filter f = new Filter() {
                         public void process(Env<AttrContext> env) {
-                            compiler.generate(compiler.desugar(List.of(env)), results);
+                            compiler.generate(compiler.desugar(ListBuffer.of(env)), results);
                         }
                     };
                 f.run(genList, classes);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Jul 10 11:25:23 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java	Thu Jul 10 16:50:38 2008 -0700
@@ -260,8 +260,11 @@
      */
     <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
         ListBuffer<Type> ts = new ListBuffer<Type>();
-        for (List<T> l = trees; l.nonEmpty(); l = l.tail)
-            ts.append(classEnter(l.head, env));
+        for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
+            Type t = classEnter(l.head, env);
+            if (t != null)
+                ts.append(t);
+        }
         return ts.toList();
     }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Jul 10 11:25:23 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java	Thu Jul 10 16:50:38 2008 -0700
@@ -63,6 +63,7 @@
 // TEMP, until we have a more efficient way to save doc comment info
 import com.sun.tools.javac.parser.DocCommentScanner;
 
+import java.util.Queue;
 import javax.lang.model.SourceVersion;
 
 /** This class could be the main entry point for GJC when GJC is used as a
@@ -460,11 +461,11 @@
             return log.nerrors;
     }
 
-    protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) {
+    protected final <T> Queue<T> stopIfError(Queue<T> queue) {
         if (errorCount() == 0)
-            return listBuffer.toList();
+            return queue;
         else
-            return List.nil();
+            return ListBuffer.lb();
     }
 
     protected final <T> List<T> stopIfError(List<T> list) {
@@ -776,8 +777,8 @@
                 break;
 
             case BY_FILE:
-                for (List<Env<AttrContext>> list : groupByFile(flow(attribute(todo))).values())
-                    generate(desugar(list));
+                for (Queue<Env<AttrContext>> queue : groupByFile(flow(attribute(todo))).values())
+                    generate(desugar(queue));
                 break;
 
             case BY_TODO:
@@ -794,7 +795,7 @@
         }
 
         if (verbose) {
-            elapsed_msec = elapsed(start_msec);;
+            elapsed_msec = elapsed(start_msec);
             printVerbose("total", Long.toString(elapsed_msec));
         }
 
@@ -1026,11 +1027,11 @@
      * Attribution of the entries in the list does not stop if any errors occur.
      * @returns a list of environments for attributd classes.
      */
-    public List<Env<AttrContext>> attribute(ListBuffer<Env<AttrContext>> envs) {
+    public Queue<Env<AttrContext>> attribute(Queue<Env<AttrContext>> envs) {
         ListBuffer<Env<AttrContext>> results = lb();
-        while (envs.nonEmpty())
-            results.append(attribute(envs.next()));
-        return results.toList();
+        while (!envs.isEmpty())
+            results.append(attribute(envs.remove()));
+        return results;
     }
 
     /**
@@ -1068,10 +1069,10 @@
      * If any errors occur, an empty list will be returned.
      * @returns the list of attributed parse trees
      */
-    public List<Env<AttrContext>> flow(List<Env<AttrContext>> envs) {
+    public Queue<Env<AttrContext>> flow(Queue<Env<AttrContext>> envs) {
         ListBuffer<Env<AttrContext>> results = lb();
-        for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) {
-            flow(l.head, results);
+        for (Env<AttrContext> env: envs) {
+            flow(env, results);
         }
         return stopIfError(results);
     }
@@ -1079,7 +1080,7 @@
     /**
      * Perform dataflow checks on an attributed parse tree.
      */
-    public List<Env<AttrContext>> flow(Env<AttrContext> env) {
+    public Queue<Env<AttrContext>> flow(Env<AttrContext> env) {
         ListBuffer<Env<AttrContext>> results = lb();
         flow(env, results);
         return stopIfError(results);
@@ -1132,10 +1133,10 @@
      * If any errors occur, an empty list will be returned.
      * @returns a list containing the classes to be generated
      */
-    public List<Pair<Env<AttrContext>, JCClassDecl>> desugar(List<Env<AttrContext>> envs) {
+    public Queue<Pair<Env<AttrContext>, JCClassDecl>> desugar(Queue<Env<AttrContext>> envs) {
         ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb();
-        for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail)
-            desugar(l.head, results);
+        for (Env<AttrContext> env: envs)
+            desugar(env, results);
         return stopIfError(results);
     }
 
@@ -1145,7 +1146,7 @@
      * the current implicitSourcePolicy is taken into account.
      * The preparation stops as soon as an error is found.
      */
-    protected void desugar(Env<AttrContext> env, ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results) {
+    protected void desugar(Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) {
         if (errorCount() > 0)
             return;
 
@@ -1180,7 +1181,7 @@
                     List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake);
                     if (pdef.head != null) {
                         assert pdef.tail.isEmpty();
-                        results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head));
+                        results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head));
                     }
                 }
                 return;
@@ -1194,7 +1195,7 @@
                     rootClasses.contains((JCClassDecl)untranslated) &&
                     ((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
                      cdef.sym.packge().getQualifiedName() == names.java_lang)) {
-                    results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef)));
+                    results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef)));
                 }
                 return;
             }
@@ -1210,7 +1211,7 @@
                 JCClassDecl cdef = (JCClassDecl)env.tree;
                 if (untranslated instanceof JCClassDecl &&
                     rootClasses.contains((JCClassDecl)untranslated)) {
-                    results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
+                    results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
                 }
                 return;
             }
@@ -1224,7 +1225,7 @@
             //generate code for each class
             for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
                 JCClassDecl cdef = (JCClassDecl)l.head;
-                results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
+                results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
             }
         }
         finally {
@@ -1275,15 +1276,14 @@
      * based upon the compiler's options.
      * Generation stops if an error occurs while writing files.
      */
-    public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list) {
-        generate(list, null);
+    public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
+        generate(queue, null);
     }
 
-    public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list, ListBuffer<JavaFileObject> results) {
+    public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, ListBuffer<JavaFileObject> results) {
         boolean usePrintSource = (stubOutput || sourceOutput || printFlat);
 
-        for (List<Pair<Env<AttrContext>, JCClassDecl>> l = list; l.nonEmpty(); l = l.tail) {
-            Pair<Env<AttrContext>, JCClassDecl> x = l.head;
+        for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
             Env<AttrContext> env = x.fst;
             JCClassDecl cdef = x.snd;
 
@@ -1325,26 +1325,17 @@
     }
 
         // where
-        Map<JCCompilationUnit, List<Env<AttrContext>>> groupByFile(List<Env<AttrContext>> list) {
+        Map<JCCompilationUnit, Queue<Env<AttrContext>>> groupByFile(Queue<Env<AttrContext>> envs) {
             // use a LinkedHashMap to preserve the order of the original list as much as possible
-            Map<JCCompilationUnit, List<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, List<Env<AttrContext>>>();
-            Set<JCCompilationUnit> fixupSet = new HashSet<JCTree.JCCompilationUnit>();
-            for (List<Env<AttrContext>> l = list; l.nonEmpty(); l = l.tail) {
-                Env<AttrContext> env = l.head;
-                List<Env<AttrContext>> sublist = map.get(env.toplevel);
-                if (sublist == null)
-                    sublist = List.of(env);
-                else {
-                    // this builds the list for the file in reverse order, so make a note
-                    // to reverse the list before returning.
-                    sublist = sublist.prepend(env);
-                    fixupSet.add(env.toplevel);
+            Map<JCCompilationUnit, Queue<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, Queue<Env<AttrContext>>>();
+            for (Env<AttrContext> env: envs) {
+                Queue<Env<AttrContext>> sublist = map.get(env.toplevel);
+                if (sublist == null) {
+                    sublist = new ListBuffer<Env<AttrContext>>();
+                    map.put(env.toplevel, sublist);
                 }
-                map.put(env.toplevel, sublist);
+                sublist.add(env);
             }
-            // fixup any lists that need reversing back to the correct order
-            for (JCTree.JCCompilationUnit tree: fixupSet)
-                map.put(tree, map.get(tree).reverse());
             return map;
         }
 
--- a/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java	Thu Jul 10 11:25:23 2008 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/ListBuffer.java	Thu Jul 10 16:50:38 2008 -0700
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.util;
 
+import java.util.AbstractQueue;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
@@ -37,12 +38,18 @@
  *  This code and its internal interfaces are subject to change or
  *  deletion without notice.</b>
  */
-public class ListBuffer<A> implements Collection<A> {
+public class ListBuffer<A> extends AbstractQueue<A> {
 
     public static <T> ListBuffer<T> lb() {
         return new ListBuffer<T>();
     }
 
+    public static <T> ListBuffer<T> of(T x) {
+        ListBuffer<T> lb = new ListBuffer<T>();
+        lb.add(x);
+        return lb;
+    }
+
     /** The list of elements of this buffer.
      */
     public List<A> elems;
@@ -119,6 +126,7 @@
     /** Append an element to buffer.
      */
     public ListBuffer<A> append(A x) {
+        x.getClass(); // null check
         if (shared) copy();
         last.head = x;
         last.setTail(new List<A>(null,null));
@@ -180,20 +188,14 @@
         return elems.head;
     }
 
-    /** Remove the first element in this buffer.
+    /** Return first element in this buffer and remove
      */
-    public void remove() {
+    public A next() {
+        A x = elems.head;
         if (elems != last) {
             elems = elems.tail;
             count--;
         }
-    }
-
-    /** Return first element in this buffer and remove
-     */
-    public A next() {
-        A x = elems.head;
-        remove();
         return x;
     }
 
@@ -219,21 +221,46 @@
     }
 
     public boolean add(A a) {
-        throw new UnsupportedOperationException();
+        append(a);
+        return true;
     }
+
     public boolean remove(Object o) {
         throw new UnsupportedOperationException();
     }
+
     public boolean containsAll(Collection<?> c) {
-        throw new UnsupportedOperationException();
+        for (Object x: c) {
+            if (!contains(x))
+                return false;
+        }
+        return true;
     }
+
     public boolean addAll(Collection<? extends A> c) {
-        throw new UnsupportedOperationException();
+        for (A a: c)
+            append(a);
+        return true;
     }
+
     public boolean removeAll(Collection<?> c) {
         throw new UnsupportedOperationException();
     }
+
     public boolean retainAll(Collection<?> c) {
         throw new UnsupportedOperationException();
     }
+
+    public boolean offer(A a) {
+        append(a);
+        return true;
+    }
+
+    public A poll() {
+        return next();
+    }
+
+    public A peek() {
+        return first();
+    }
 }