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;
}
// 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 @@ public class JavacTaskImpl extends JavacTask {
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
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);

View File

@ -260,8 +260,11 @@ public class Enter extends JCTree.Visitor {
*/
<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();
}

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
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
}
if (verbose) {
elapsed_msec = elapsed(start_msec);;
elapsed_msec = elapsed(start_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.
* @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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* 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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
/**
* 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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* 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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* 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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
//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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
* 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 @@ public class JavaCompiler implements ClassReader.SourceCompleter {
}
// 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;
}

View File

@ -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 @@ import java.util.NoSuchElementException;
* 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 @@ public class ListBuffer<A> implements Collection<A> {
/** 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 @@ public class ListBuffer<A> implements Collection<A> {
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
*/
public A next() {
A x = elems.head;
remove();
if (elems != last) {
elems = elems.tail;
count--;
}
return x;
}
@ -219,21 +221,46 @@ public class ListBuffer<A> implements Collection<A> {
}
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();
}
}