6724551: Use Queues instead of Lists to link compiler phases

Reviewed-by: darcy
This commit is contained in:
Jonathan Gibbons 2008-07-10 16:50:38 -07:00
parent aa985271fd
commit efd2515395
4 changed files with 86 additions and 65 deletions

View File

@ -381,8 +381,8 @@ public class JavacTaskImpl extends JavacTask {
return results; return results;
} }
// where // where
private void handleFlowResults(List<Env<AttrContext>> list, ListBuffer<Element> elems) { private void handleFlowResults(Queue<Env<AttrContext>> queue, ListBuffer<Element> elems) {
for (Env<AttrContext> env: list) { for (Env<AttrContext> env: queue) {
switch (env.tree.getTag()) { switch (env.tree.getTag()) {
case JCTree.CLASSDEF: case JCTree.CLASSDEF:
JCClassDecl cdef = (JCClassDecl) env.tree; JCClassDecl cdef = (JCClassDecl) env.tree;
@ -396,7 +396,7 @@ public class JavacTaskImpl extends JavacTask {
break; break;
} }
} }
genList.appendList(list); genList.addAll(queue);
} }
@ -424,13 +424,13 @@ public class JavacTaskImpl extends JavacTask {
analyze(null); // ensure all classes have been parsed, entered, and analyzed analyze(null); // ensure all classes have been parsed, entered, and analyzed
if (classes == null) { if (classes == null) {
compiler.generate(compiler.desugar(genList.toList()), results); compiler.generate(compiler.desugar(genList), results);
genList.clear(); genList.clear();
} }
else { else {
Filter f = new Filter() { Filter f = new Filter() {
public void process(Env<AttrContext> env) { 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); f.run(genList, classes);

View File

@ -260,8 +260,11 @@ public class Enter extends JCTree.Visitor {
*/ */
<T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) { <T extends JCTree> List<Type> classEnter(List<T> trees, Env<AttrContext> env) {
ListBuffer<Type> ts = new ListBuffer<Type>(); ListBuffer<Type> ts = new ListBuffer<Type>();
for (List<T> l = trees; l.nonEmpty(); l = l.tail) for (List<T> l = trees; l.nonEmpty(); l = l.tail) {
ts.append(classEnter(l.head, env)); Type t = classEnter(l.head, env);
if (t != null)
ts.append(t);
}
return ts.toList(); return ts.toList();
} }

View File

@ -63,6 +63,7 @@ import static com.sun.tools.javac.util.ListBuffer.lb;
// TEMP, until we have a more efficient way to save doc comment info // TEMP, until we have a more efficient way to save doc comment info
import com.sun.tools.javac.parser.DocCommentScanner; import com.sun.tools.javac.parser.DocCommentScanner;
import java.util.Queue;
import javax.lang.model.SourceVersion; import javax.lang.model.SourceVersion;
/** This class could be the main entry point for GJC when GJC is used as a /** This class could be the main entry point for GJC when GJC is used as a
@ -460,11 +461,11 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
return log.nerrors; return log.nerrors;
} }
protected final <T> List<T> stopIfError(ListBuffer<T> listBuffer) { protected final <T> Queue<T> stopIfError(Queue<T> queue) {
if (errorCount() == 0) if (errorCount() == 0)
return listBuffer.toList(); return queue;
else else
return List.nil(); return ListBuffer.lb();
} }
protected final <T> List<T> stopIfError(List<T> list) { protected final <T> List<T> stopIfError(List<T> list) {
@ -776,8 +777,8 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
break; break;
case BY_FILE: case BY_FILE:
for (List<Env<AttrContext>> list : groupByFile(flow(attribute(todo))).values()) for (Queue<Env<AttrContext>> queue : groupByFile(flow(attribute(todo))).values())
generate(desugar(list)); generate(desugar(queue));
break; break;
case BY_TODO: case BY_TODO:
@ -794,7 +795,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
} }
if (verbose) { if (verbose) {
elapsed_msec = elapsed(start_msec);; elapsed_msec = elapsed(start_msec);
printVerbose("total", Long.toString(elapsed_msec)); printVerbose("total", Long.toString(elapsed_msec));
} }
@ -1026,11 +1027,11 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* Attribution of the entries in the list does not stop if any errors occur. * Attribution of the entries in the list does not stop if any errors occur.
* @returns a list of environments for attributd classes. * @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(); ListBuffer<Env<AttrContext>> results = lb();
while (envs.nonEmpty()) while (!envs.isEmpty())
results.append(attribute(envs.next())); results.append(attribute(envs.remove()));
return results.toList(); return results;
} }
/** /**
@ -1068,10 +1069,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* If any errors occur, an empty list will be returned. * If any errors occur, an empty list will be returned.
* @returns the list of attributed parse trees * @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(); ListBuffer<Env<AttrContext>> results = lb();
for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) { for (Env<AttrContext> env: envs) {
flow(l.head, results); flow(env, results);
} }
return stopIfError(results); return stopIfError(results);
} }
@ -1079,7 +1080,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
/** /**
* Perform dataflow checks on an attributed parse tree. * 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(); ListBuffer<Env<AttrContext>> results = lb();
flow(env, results); flow(env, results);
return stopIfError(results); return stopIfError(results);
@ -1132,10 +1133,10 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* If any errors occur, an empty list will be returned. * If any errors occur, an empty list will be returned.
* @returns a list containing the classes to be generated * @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(); ListBuffer<Pair<Env<AttrContext>, JCClassDecl>> results = lb();
for (List<Env<AttrContext>> l = envs; l.nonEmpty(); l = l.tail) for (Env<AttrContext> env: envs)
desugar(l.head, results); desugar(env, results);
return stopIfError(results); return stopIfError(results);
} }
@ -1145,7 +1146,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* the current implicitSourcePolicy is taken into account. * the current implicitSourcePolicy is taken into account.
* The preparation stops as soon as an error is found. * 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) if (errorCount() > 0)
return; return;
@ -1180,7 +1181,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake); List<JCTree> pdef = lower.translateTopLevelClass(env, env.tree, localMake);
if (pdef.head != null) { if (pdef.head != null) {
assert pdef.tail.isEmpty(); 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; return;
@ -1194,7 +1195,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
rootClasses.contains((JCClassDecl)untranslated) && rootClasses.contains((JCClassDecl)untranslated) &&
((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 || ((cdef.mods.flags & (Flags.PROTECTED|Flags.PUBLIC)) != 0 ||
cdef.sym.packge().getQualifiedName() == names.java_lang)) { 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; return;
} }
@ -1210,7 +1211,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
JCClassDecl cdef = (JCClassDecl)env.tree; JCClassDecl cdef = (JCClassDecl)env.tree;
if (untranslated instanceof JCClassDecl && if (untranslated instanceof JCClassDecl &&
rootClasses.contains((JCClassDecl)untranslated)) { rootClasses.contains((JCClassDecl)untranslated)) {
results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
} }
return; return;
} }
@ -1224,7 +1225,7 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
//generate code for each class //generate code for each class
for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) { for (List<JCTree> l = cdefs; l.nonEmpty(); l = l.tail) {
JCClassDecl cdef = (JCClassDecl)l.head; JCClassDecl cdef = (JCClassDecl)l.head;
results.append(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef)); results.add(new Pair<Env<AttrContext>, JCClassDecl>(env, cdef));
} }
} }
finally { finally {
@ -1275,15 +1276,14 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* based upon the compiler's options. * based upon the compiler's options.
* Generation stops if an error occurs while writing files. * Generation stops if an error occurs while writing files.
*/ */
public void generate(List<Pair<Env<AttrContext>, JCClassDecl>> list) { public void generate(Queue<Pair<Env<AttrContext>, JCClassDecl>> queue) {
generate(list, null); 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); boolean usePrintSource = (stubOutput || sourceOutput || printFlat);
for (List<Pair<Env<AttrContext>, JCClassDecl>> l = list; l.nonEmpty(); l = l.tail) { for (Pair<Env<AttrContext>, JCClassDecl> x: queue) {
Pair<Env<AttrContext>, JCClassDecl> x = l.head;
Env<AttrContext> env = x.fst; Env<AttrContext> env = x.fst;
JCClassDecl cdef = x.snd; JCClassDecl cdef = x.snd;
@ -1325,26 +1325,17 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
} }
// where // 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 // 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>>>(); Map<JCCompilationUnit, Queue<Env<AttrContext>>> map = new LinkedHashMap<JCCompilationUnit, Queue<Env<AttrContext>>>();
Set<JCCompilationUnit> fixupSet = new HashSet<JCTree.JCCompilationUnit>(); for (Env<AttrContext> env: envs) {
for (List<Env<AttrContext>> l = list; l.nonEmpty(); l = l.tail) { Queue<Env<AttrContext>> sublist = map.get(env.toplevel);
Env<AttrContext> env = l.head; if (sublist == null) {
List<Env<AttrContext>> sublist = map.get(env.toplevel); sublist = new ListBuffer<Env<AttrContext>>();
if (sublist == null) map.put(env.toplevel, sublist);
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.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; return map;
} }

View File

@ -25,6 +25,7 @@
package com.sun.tools.javac.util; package com.sun.tools.javac.util;
import java.util.AbstractQueue;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
@ -37,12 +38,18 @@ import java.util.NoSuchElementException;
* This code and its internal interfaces are subject to change or * This code and its internal interfaces are subject to change or
* deletion without notice.</b> * deletion without notice.</b>
*/ */
public class ListBuffer<A> implements Collection<A> { public class ListBuffer<A> extends AbstractQueue<A> {
public static <T> ListBuffer<T> lb() { public static <T> ListBuffer<T> lb() {
return new ListBuffer<T>(); 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. /** The list of elements of this buffer.
*/ */
public List<A> elems; public List<A> elems;
@ -119,6 +126,7 @@ public class ListBuffer<A> implements Collection<A> {
/** Append an element to buffer. /** Append an element to buffer.
*/ */
public ListBuffer<A> append(A x) { public ListBuffer<A> append(A x) {
x.getClass(); // null check
if (shared) copy(); if (shared) copy();
last.head = x; last.head = x;
last.setTail(new List<A>(null,null)); last.setTail(new List<A>(null,null));
@ -180,20 +188,14 @@ public class ListBuffer<A> implements Collection<A> {
return elems.head; return elems.head;
} }
/** Remove the first element in this buffer.
*/
public void remove() {
if (elems != last) {
elems = elems.tail;
count--;
}
}
/** Return first element in this buffer and remove /** Return first element in this buffer and remove
*/ */
public A next() { public A next() {
A x = elems.head; A x = elems.head;
remove(); if (elems != last) {
elems = elems.tail;
count--;
}
return x; return x;
} }
@ -219,21 +221,46 @@ public class ListBuffer<A> implements Collection<A> {
} }
public boolean add(A a) { public boolean add(A a) {
throw new UnsupportedOperationException(); append(a);
return true;
} }
public boolean remove(Object o) { public boolean remove(Object o) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean containsAll(Collection<?> c) { 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) { public boolean addAll(Collection<? extends A> c) {
throw new UnsupportedOperationException(); for (A a: c)
append(a);
return true;
} }
public boolean removeAll(Collection<?> c) { public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean retainAll(Collection<?> c) { public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public boolean offer(A a) {
append(a);
return true;
}
public A poll() {
return next();
}
public A peek() {
return first();
}
} }