8189747: JDK9 javax.lang.model.util.Elements#getTypeElement regressed 1000x in performance

Caching the results of Elements.getTypeElement/getPackageElement

Reviewed-by: darcy
This commit is contained in:
Jan Lahoda 2018-07-16 12:35:25 +02:00
parent 2131cb484e
commit fe80e55647
3 changed files with 78 additions and 31 deletions

View file

@ -26,9 +26,11 @@
package com.sun.tools.javac.model;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -184,7 +186,9 @@ public class JavacElements implements Elements {
}
private final Set<String> alreadyWarnedDuplicates = new HashSet<>();
private final Map<Pair<String, String>, Optional<Symbol>> resultCache = new HashMap<>();
@SuppressWarnings("unchecked")
private <S extends Symbol> S unboundNameToSymbol(String methodName,
String nameStr,
Class<S> clazz) {
@ -192,6 +196,7 @@ public class JavacElements implements Elements {
return nameToSymbol(syms.noModule, nameStr, clazz);
}
return (S) resultCache.computeIfAbsent(Pair.of(methodName, nameStr), p -> {
Set<S> found = new LinkedHashSet<>();
for (ModuleSymbol msym : modules.allModules()) {
@ -215,7 +220,7 @@ public class JavacElements implements Elements {
}
if (found.size() == 1) {
return found.iterator().next();
return Optional.of(found.iterator().next());
} else if (found.size() > 1) {
//more than one element found, produce a note:
if (alreadyWarnedDuplicates.add(methodName + ":" + nameStr)) {
@ -225,11 +230,12 @@ public class JavacElements implements Elements {
.collect(Collectors.joining(", "));
log.note(Notes.MultipleElements(methodName, nameStr, moduleNames));
}
return null;
return Optional.empty();
} else {
//not found, or more than one element found:
return null;
//not found:
return Optional.empty();
}
}).orElse(null);
}
/**
@ -787,4 +793,8 @@ public class JavacElements implements Elements {
throw new IllegalArgumentException(o.toString());
return clazz.cast(o);
}
public void newRound() {
resultCache.clear();
}
}

View file

@ -1270,6 +1270,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
modules.newRound();
types.newRound();
annotate.newRound();
elementUtils.newRound();
boolean foundError = false;

View file

@ -23,7 +23,7 @@
/**
* @test
* @bug 8133884 8162711 8133896 8172158 8172262 8173636 8175119
* @bug 8133884 8162711 8133896 8172158 8172262 8173636 8175119 8189747
* @summary Verify that annotation processing works.
* @library /tools/lib
* @modules
@ -1389,6 +1389,19 @@ public class AnnotationProcessing extends ModuleTestBase {
.run()
.writeAll();
//from source:
new JavacTask(tb)
.options("--module-source-path", moduleSrc.toString(),
"--source-path", src.toString(),
"-processorpath", System.getProperty("test.class.path"),
"-processor", UnboundLookupGenerate.class.getName(),
"-XDrawDiagnostics")
.outdir(classes)
.files(findJavaFiles(moduleSrc))
.run()
.writeAll()
.getOutput(OutputKind.DIRECT);
}
@SupportedAnnotationTypes("*")
@ -1486,6 +1499,29 @@ public class AnnotationProcessing extends ModuleTestBase {
}
@SupportedAnnotationTypes("*")
public static final class UnboundLookupGenerate extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (processingEnv.getElementUtils().getTypeElement("nue.Nue") == null) {
try (Writer w = processingEnv.getFiler().createSourceFile("m1x/nue.Nue").openWriter()) {
w.write("package nue; public class Nue {}");
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}
@Test
public void testWrongDefaultTargetModule(Path base) throws Exception {
Path src = base.resolve("src");