8221118: Avoid eagerly creating JCDiagnostic for CompletionFailures
Reviewed-by: jjg, mcimadamore, forax
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Tue Mar 26 12:12:49 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Fri Mar 29 07:38:34 2019 -0700
@@ -33,6 +33,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
+import java.util.function.Supplier;
import javax.lang.model.SourceVersion;
import javax.tools.JavaFileManager;
@@ -222,7 +223,7 @@
jrtIndex = useCtProps && JRTIndex.isAvailable() ? JRTIndex.getSharedInstance() : null;
profile = Profile.instance(context);
- cachedCompletionFailure = new CompletionFailure(null, (JCDiagnostic) null, dcfh);
+ cachedCompletionFailure = new CompletionFailure(null, () -> null, dcfh);
cachedCompletionFailure.setStackTrace(new StackTraceElement[0]);
}
@@ -298,9 +299,12 @@
try {
fillIn(p);
} catch (IOException ex) {
- JCDiagnostic msg =
- diagFactory.fragment(Fragments.ExceptionMessage(ex.getLocalizedMessage()));
- throw new CompletionFailure(sym, msg, dcfh).initCause(ex);
+ throw new CompletionFailure(
+ sym,
+ () -> diagFactory.fragment(
+ Fragments.ExceptionMessage(ex.getLocalizedMessage())),
+ dcfh)
+ .initCause(ex);
}
}
if (!reader.filling)
@@ -337,9 +341,8 @@
*/
void fillIn(ClassSymbol c) {
if (completionFailureName == c.fullname) {
- JCDiagnostic msg =
- diagFactory.fragment(Fragments.UserSelectedCompletionFailure);
- throw new CompletionFailure(c, msg, dcfh);
+ throw new CompletionFailure(
+ c, () -> diagFactory.fragment(Fragments.UserSelectedCompletionFailure), dcfh);
}
currentOwner = c;
JavaFileObject classfile = c.classfile;
@@ -390,16 +393,15 @@
}
// where
private CompletionFailure classFileNotFound(ClassSymbol c) {
- JCDiagnostic diag =
- diagFactory.fragment(Fragments.ClassFileNotFound(c.flatname));
- return newCompletionFailure(c, diag);
+ return newCompletionFailure(
+ c, () -> diagFactory.fragment(Fragments.ClassFileNotFound(c.flatname)));
}
/** Static factory for CompletionFailure objects.
* In practice, only one can be used at a time, so we share one
* to reduce the expense of allocating new exception objects.
*/
private CompletionFailure newCompletionFailure(TypeSymbol c,
- JCDiagnostic diag) {
+ Supplier<JCDiagnostic> diag) {
if (!cacheCompletionFailure) {
// log.warning("proc.messager",
// Log.getLocalizedString("class.file.not.found", c.flatname));
@@ -408,7 +410,7 @@
} else {
CompletionFailure result = cachedCompletionFailure;
result.sym = c;
- result.diag = diag;
+ result.resetDiagnostic(diag);
return result;
}
}
@@ -782,7 +784,7 @@
public BadClassFile(TypeSymbol sym, JavaFileObject file, JCDiagnostic diag,
JCDiagnostic.Factory diagFactory, DeferredCompletionFailureHandler dcfh) {
- super(sym, createBadClassFileDiagnostic(file, diag, diagFactory), dcfh);
+ super(sym, () -> createBadClassFileDiagnostic(file, diag, diagFactory), dcfh);
}
// where
private static JCDiagnostic createBadClassFileDiagnostic(
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Tue Mar 26 12:12:49 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Fri Mar 29 07:38:34 2019 -0700
@@ -32,6 +32,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
+import java.util.function.Supplier;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
@@ -2131,26 +2132,31 @@
/** A diagnostic object describing the failure
*/
- public JCDiagnostic diag;
+ private JCDiagnostic diag;
- public CompletionFailure(Symbol sym, JCDiagnostic diag, DeferredCompletionFailureHandler dcfh) {
+ private Supplier<JCDiagnostic> diagSupplier;
+
+ public CompletionFailure(Symbol sym, Supplier<JCDiagnostic> diagSupplier, DeferredCompletionFailureHandler dcfh) {
this.dcfh = dcfh;
this.sym = sym;
- this.diag = diag;
+ this.diagSupplier = diagSupplier;
// this.printStackTrace();//DEBUG
}
public JCDiagnostic getDiagnostic() {
+ if (diag == null && diagSupplier != null) {
+ diag = diagSupplier.get();
+ }
return diag;
}
@Override
public String getMessage() {
- return diag.getMessage(null);
+ return getDiagnostic().getMessage(null);
}
public JCDiagnostic getDetailValue() {
- return diag;
+ return getDiagnostic();
}
@Override
@@ -2159,6 +2165,11 @@
return this;
}
+ public void resetDiagnostic(Supplier<JCDiagnostic> diagSupplier) {
+ this.diagSupplier = diagSupplier;
+ this.diag = null;
+ }
+
}
/**
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Tue Mar 26 12:12:49 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Mar 29 07:38:34 2019 -0700
@@ -3079,7 +3079,7 @@
}
} catch (Exception e) {
throw new CompletionFailure(sym,
- ClassReader.this.diagFactory.fragment(Fragments.ExceptionMessage(e.getMessage())),
+ () -> ClassReader.this.diagFactory.fragment(Fragments.ExceptionMessage(e.getMessage())),
dcfh);
}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Tue Mar 26 12:12:49 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Fri Mar 29 07:38:34 2019 -0700
@@ -805,9 +805,8 @@
*/
public void readSourceFile(JCCompilationUnit tree, ClassSymbol c) throws CompletionFailure {
if (completionFailureName == c.fullname) {
- JCDiagnostic msg =
- diagFactory.fragment(Fragments.UserSelectedCompletionFailure);
- throw new CompletionFailure(c, msg, dcfh);
+ throw new CompletionFailure(
+ c, () -> diagFactory.fragment(Fragments.UserSelectedCompletionFailure), dcfh);
}
JavaFileObject filename = c.classfile;
JavaFileObject prev = log.useSource(filename);
@@ -835,7 +834,7 @@
// have enough modules available to access java.lang, and
// so risk getting FatalError("no.java.lang") from MemberEnter.
if (!modules.enter(List.of(tree), c)) {
- throw new CompletionFailure(c, diags.fragment(Fragments.CantResolveModules), dcfh);
+ throw new CompletionFailure(c, () -> diags.fragment(Fragments.CantResolveModules), dcfh);
}
enter.complete(List.of(tree), c);
--- a/test/langtools/tools/javac/defaultMethods/BadClassfile.java Tue Mar 26 12:12:49 2019 -0400
+++ b/test/langtools/tools/javac/defaultMethods/BadClassfile.java Fri Mar 29 07:38:34 2019 -0700
@@ -79,7 +79,7 @@
clazz.complete();
} catch (BadClassFile f) {
- JCDiagnostic embeddedDiag = (JCDiagnostic) f.diag.getArgs()[1];
+ JCDiagnostic embeddedDiag = (JCDiagnostic) f.getDiagnostic().getArgs()[1];
assertEquals(expected, embeddedDiag.getCode());
assertEquals(Integer.toString(Target.JDK1_7.majorVersion), embeddedDiag.getArgs()[0]);
assertEquals(Integer.toString(Target.JDK1_7.minorVersion), embeddedDiag.getArgs()[1]);