Thu, 10 Jul 2008 16:50:38 -0700
6724551: Use Queues instead of Lists to link compiler phases
Reviewed-by: darcy
1.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Jul 10 11:25:23 2008 -0700 1.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java Thu Jul 10 16:50:38 2008 -0700 1.3 @@ -381,8 +381,8 @@ 1.4 return results; 1.5 } 1.6 // where 1.7 - private void handleFlowResults(List<Env<AttrContext>> list, ListBuffer<Element> elems) { 1.8 - for (Env<AttrContext> env: list) { 1.9 + private void handleFlowResults(Queue<Env<AttrContext>> queue, ListBuffer<Element> elems) { 1.10 + for (Env<AttrContext> env: queue) { 1.11 switch (env.tree.getTag()) { 1.12 case JCTree.CLASSDEF: 1.13 JCClassDecl cdef = (JCClassDecl) env.tree; 1.14 @@ -396,7 +396,7 @@ 1.15 break; 1.16 } 1.17 } 1.18 - genList.appendList(list); 1.19 + genList.addAll(queue); 1.20 } 1.21 1.22 1.23 @@ -424,13 +424,13 @@ 1.24 analyze(null); // ensure all classes have been parsed, entered, and analyzed 1.25 1.26 if (classes == null) { 1.27 - compiler.generate(compiler.desugar(genList.toList()), results); 1.28 + compiler.generate(compiler.desugar(genList), results); 1.29 genList.clear(); 1.30 } 1.31 else { 1.32 Filter f = new Filter() { 1.33 public void process(Env<AttrContext> env) { 1.34 - compiler.generate(compiler.desugar(List.of(env)), results); 1.35 + compiler.generate(compiler.desugar(ListBuffer.of(env)), results); 1.36 } 1.37 }; 1.38 f.run(genList, classes);
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Enter.java Thu Jul 10 11:25:23 2008 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Enter.java Thu Jul 10 16:50:38 2008 -0700 2.3 @@ -260,8 +260,11 @@ 2.4 */ 2.5 <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) { 2.6 ListBuffer<Type> ts = new ListBuffer<Type>(); 2.7 - for (List<T> l = trees; l.nonEmpty(); l = l.tail) 2.8 - ts.append(classEnter(l.head, env)); 2.9 + for (List<T> l = trees; l.nonEmpty(); l = l.tail) { 2.10 + Type t = classEnter(l.head, env); 2.11 + if (t != null) 2.12 + ts.append(t); 2.13 + } 2.14 return ts.toList(); 2.15 } 2.16
3.1 --- a/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Jul 10 11:25:23 2008 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Jul 10 16:50:38 2008 -0700 3.3 @@ -63,6 +63,7 @@ 3.4 // TEMP, until we have a more efficient way to save doc comment info 3.5 import com.sun.tools.javac.parser.DocCommentScanner; 3.6 3.7 +import java.util.Queue; 3.8 import javax.lang.model.SourceVersion; 3.9 3.10 /** This class could be the main entry point for GJC when GJC is used as a 3.11 @@ -460,11 +461,11 @@ 3.12 return log.nerrors; 3.13 } 3.14 3.15 - protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) { 3.16 + protected final <T> Queue<T> stopIfError(Queue<T> queue) { 3.17 if (errorCount() == 0) 3.18 - return listBuffer.toList(); 3.19 + return queue; 3.20 else 3.21 - return List.nil(); 3.22 + return ListBuffer.lb(); 3.23 } 3.24 3.25 protected final <T> List<T> stopIfError(List<T> list) { 3.26 @@ -776,8 +777,8 @@ 3.27 break; 3.28 3.29 case BY_FILE: 3.30 - for (List<Env<AttrContext>> list : groupByFile(flow(attribute(todo))).values()) 3.31 - generate(desugar(list)); 3.32 + for (Queue<Env<AttrContext>> queue : groupByFile(flow(attribute(todo))).values()) 3.33 + generate(desugar(queue)); 3.34 break; 3.35 3.36 case BY_TODO: 3.37 @@ -794,7 +795,7 @@ 3.38 } 3.39 3.40 if (verbose) { 3.41 - elapsed_msec = elapsed(start_msec);; 3.42 + elapsed_msec = elapsed(start_msec); 3.43 printVerbose("total", Long.toString(elapsed_msec)); 3.44 } 3.45 3.46 @@ -1026,11 +1027,11 @@ 3.47 * Attribution of the entries in the list does not stop if any errors occur. 3.48 * @returns a list of environments for attributd classes. 3.49 */ 3.50 - public List<Env<AttrContext>> attribute(ListBuffer<Env<AttrContext>> envs) { 3.51 + public Queue<Env<AttrContext>> attribute(Queue<Env<AttrContext>> envs) { 3.52 ListBuffer<Env<AttrContext>> results = lb(); 3.53 - while (envs.nonEmpty()) 3.54 - results.append(attribute(envs.next())); 3.55 - return results.toList(); 3.56 + while (!envs.isEmpty()) 3.57 + results.append(attribute(envs.remove())); 3.58 + return results; 3.59 } 3.60 3.61 /** 3.62 @@ -1068,10 +1069,10 @@ 3.63 * If any errors occur, an empty list will be returned. 3.64 * @returns the list of attributed parse trees 3.65 */ 3.66 - public List<Env<AttrContext>> flow(List<Env<AttrContext>> envs) { 3.67 + public Queue<Env<AttrContext>> flow(Queue<Env<AttrContext>> envs) { 3.68 ListBuffer<Env<AttrContext>> results = lb(); 3.69 - for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) { 3.70 - flow(l.head, results); 3.71 + for (Env<AttrContext> env: envs) { 3.72 + flow(env, results); 3.73 } 3.74 return stopIfError(results); 3.75 } 3.76 @@ -1079,7 +1080,7 @@ 3.77 /** 3.78 * Perform dataflow checks on an attributed parse tree. 3.79 */ 3.80 - public List<Env<AttrContext>> flow(Env<AttrContext> env) { 3.81 + public Queue<Env<AttrContext>> flow(Env<AttrContext> env) { 3.82 ListBuffer<Env<AttrContext>> results = lb(); 3.83 flow(env, results); 3.84 return stopIfError(results); 3.85 @@ -1132,10 +1133,10 @@ 3.86 * If any errors occur, an empty list will be returned. 3.87 * @returns a list containing the classes to be generated 3.88 */ 3.89 - public List<Pair<Env<AttrContext>, JCClassDecl>> desugar(List<Env<AttrContext>> envs) { 3.90 + public Queue<Pair<Env<AttrContext>, JCClassDecl>> desugar(Queue<Env<AttrContext>> envs) { 3.91 ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb(); 3.92 - for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) 3.93 - desugar(l.head, results); 3.94 + for (Env<AttrContext> env: envs) 3.95 + desugar(env, results); 3.96 return stopIfError(results); 3.97 } 3.98 3.99 @@ -1145,7 +1146,7 @@ 3.100 * the current implicitSourcePolicy is taken into account. 3.101 * The preparation stops as soon as an error is found. 3.102 */ 3.103 - protected void desugar(Env<AttrContext> env, ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results) { 3.104 + protected void desugar(Env<AttrContext> env, Queue<Pair<Env<AttrContext>, JCClassDecl>> results) { 3.105 if (errorCount() > 0) 3.106 return; 3.107 3.108 @@ -1180,7 +1181,7 @@ 3.109 List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake); 3.110 if (pdef.head != null) { 3.111 assert pdef.tail.isEmpty(); 3.112 - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head)); 3.113 + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, (JCClassDecl)pdef.head)); 3.114 } 3.115 } 3.116 return; 3.117 @@ -1194,7 +1195,7 @@ 3.118 rootClasses.contains((JCClassDecl)untranslated) && 3.119 ((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 || 3.120 cdef.sym.packge().getQualifiedName() == names.java_lang)) { 3.121 - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef))); 3.122 + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, removeMethodBodies(cdef))); 3.123 } 3.124 return; 3.125 } 3.126 @@ -1210,7 +1211,7 @@ 3.127 JCClassDecl cdef = (JCClassDecl)env.tree; 3.128 if (untranslated instanceof JCClassDecl && 3.129 rootClasses.contains((JCClassDecl)untranslated)) { 3.130 - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); 3.131 + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); 3.132 } 3.133 return; 3.134 } 3.135 @@ -1224,7 +1225,7 @@ 3.136 //generate code for each class 3.137 for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) { 3.138 JCClassDecl cdef = (JCClassDecl)l.head; 3.139 - results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); 3.140 + results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); 3.141 } 3.142 } 3.143 finally { 3.144 @@ -1275,15 +1276,14 @@ 3.145 * based upon the compiler's options. 3.146 * Generation stops if an error occurs while writing files. 3.147 */ 3.148 - public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list) { 3.149 - generate(list, null); 3.150 + public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) { 3.151 + generate(queue, null); 3.152 } 3.153 3.154 - public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list, ListBuffer<JavaFileObject> results) { 3.155 + public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue, ListBuffer<JavaFileObject> results) { 3.156 boolean usePrintSource = (stubOutput || sourceOutput || printFlat); 3.157 3.158 - for (List<Pair<Env<AttrContext>, JCClassDecl>> l = list; l.nonEmpty(); l = l.tail) { 3.159 - Pair<Env<AttrContext>, JCClassDecl> x = l.head; 3.160 + for (Pair<Env<AttrContext>, JCClassDecl> x: queue) { 3.161 Env<AttrContext> env = x.fst; 3.162 JCClassDecl cdef = x.snd; 3.163 3.164 @@ -1325,26 +1325,17 @@ 3.165 } 3.166 3.167 // where 3.168 - Map<JCCompilationUnit, List<Env<AttrContext>>> groupByFile(List<Env<AttrContext>> list) { 3.169 + Map<JCCompilationUnit, Queue<Env<AttrContext>>> groupByFile(Queue<Env<AttrContext>> envs) { 3.170 // use a LinkedHashMap to preserve the order of the original list as much as possible 3.171 - Map<JCCompilationUnit, List<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, List<Env<AttrContext>>>(); 3.172 - Set<JCCompilationUnit> fixupSet = new HashSet<JCTree.JCCompilationUnit>(); 3.173 - for (List<Env<AttrContext>> l = list; l.nonEmpty(); l = l.tail) { 3.174 - Env<AttrContext> env = l.head; 3.175 - List<Env<AttrContext>> sublist = map.get(env.toplevel); 3.176 - if (sublist == null) 3.177 - sublist = List.of(env); 3.178 - else { 3.179 - // this builds the list for the file in reverse order, so make a note 3.180 - // to reverse the list before returning. 3.181 - sublist = sublist.prepend(env); 3.182 - fixupSet.add(env.toplevel); 3.183 + Map<JCCompilationUnit, Queue<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, Queue<Env<AttrContext>>>(); 3.184 + for (Env<AttrContext> env: envs) { 3.185 + Queue<Env<AttrContext>> sublist = map.get(env.toplevel); 3.186 + if (sublist == null) { 3.187 + sublist = new ListBuffer<Env<AttrContext>>(); 3.188 + map.put(env.toplevel, sublist); 3.189 } 3.190 - map.put(env.toplevel, sublist); 3.191 + sublist.add(env); 3.192 } 3.193 - // fixup any lists that need reversing back to the correct order 3.194 - for (JCTree.JCCompilationUnit tree: fixupSet) 3.195 - map.put(tree, map.get(tree).reverse()); 3.196 return map; 3.197 } 3.198
4.1 --- a/src/share/classes/com/sun/tools/javac/util/ListBuffer.java Thu Jul 10 11:25:23 2008 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/util/ListBuffer.java Thu Jul 10 16:50:38 2008 -0700 4.3 @@ -25,6 +25,7 @@ 4.4 4.5 package com.sun.tools.javac.util; 4.6 4.7 +import java.util.AbstractQueue; 4.8 import java.util.Collection; 4.9 import java.util.Iterator; 4.10 import java.util.NoSuchElementException; 4.11 @@ -37,12 +38,18 @@ 4.12 * This code and its internal interfaces are subject to change or 4.13 * deletion without notice.</b> 4.14 */ 4.15 -public class ListBuffer<A> implements Collection<A> { 4.16 +public class ListBuffer<A> extends AbstractQueue<A> { 4.17 4.18 public static <T> ListBuffer<T> lb() { 4.19 return new ListBuffer<T>(); 4.20 } 4.21 4.22 + public static <T> ListBuffer<T> of(T x) { 4.23 + ListBuffer<T> lb = new ListBuffer<T>(); 4.24 + lb.add(x); 4.25 + return lb; 4.26 + } 4.27 + 4.28 /** The list of elements of this buffer. 4.29 */ 4.30 public List<A> elems; 4.31 @@ -119,6 +126,7 @@ 4.32 /** Append an element to buffer. 4.33 */ 4.34 public ListBuffer<A> append(A x) { 4.35 + x.getClass(); // null check 4.36 if (shared) copy(); 4.37 last.head = x; 4.38 last.setTail(new List<A>(null,null)); 4.39 @@ -180,20 +188,14 @@ 4.40 return elems.head; 4.41 } 4.42 4.43 - /** Remove the first element in this buffer. 4.44 + /** Return first element in this buffer and remove 4.45 */ 4.46 - public void remove() { 4.47 + public A next() { 4.48 + A x = elems.head; 4.49 if (elems != last) { 4.50 elems = elems.tail; 4.51 count--; 4.52 } 4.53 - } 4.54 - 4.55 - /** Return first element in this buffer and remove 4.56 - */ 4.57 - public A next() { 4.58 - A x = elems.head; 4.59 - remove(); 4.60 return x; 4.61 } 4.62 4.63 @@ -219,21 +221,46 @@ 4.64 } 4.65 4.66 public boolean add(A a) { 4.67 - throw new UnsupportedOperationException(); 4.68 + append(a); 4.69 + return true; 4.70 } 4.71 + 4.72 public boolean remove(Object o) { 4.73 throw new UnsupportedOperationException(); 4.74 } 4.75 + 4.76 public boolean containsAll(Collection<?> c) { 4.77 - throw new UnsupportedOperationException(); 4.78 + for (Object x: c) { 4.79 + if (!contains(x)) 4.80 + return false; 4.81 + } 4.82 + return true; 4.83 } 4.84 + 4.85 public boolean addAll(Collection<? extends A> c) { 4.86 - throw new UnsupportedOperationException(); 4.87 + for (A a: c) 4.88 + append(a); 4.89 + return true; 4.90 } 4.91 + 4.92 public boolean removeAll(Collection<?> c) { 4.93 throw new UnsupportedOperationException(); 4.94 } 4.95 + 4.96 public boolean retainAll(Collection<?> c) { 4.97 throw new UnsupportedOperationException(); 4.98 } 4.99 + 4.100 + public boolean offer(A a) { 4.101 + append(a); 4.102 + return true; 4.103 + } 4.104 + 4.105 + public A poll() { 4.106 + return next(); 4.107 + } 4.108 + 4.109 + public A peek() { 4.110 + return first(); 4.111 + } 4.112 }