8337037: compiler internal options are not printing the stacktrace after a compiler crash

Reviewed-by: mcimadamore
This commit is contained in:
Vicente Romero 2024-07-25 17:03:45 +00:00
parent 81ed028717
commit cf0d9e0e52
9 changed files with 108 additions and 63 deletions

View File

@ -62,6 +62,8 @@ import static com.sun.tools.javac.code.Symbol.*;
import static com.sun.tools.javac.code.Type.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.jvm.ClassFile.externalize;
import static com.sun.tools.javac.main.Option.DOE;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
/**
@ -99,6 +101,7 @@ public class Types {
final Name capturedName;
public final Warner noWarnings;
public final boolean dumpStacktraceOnError;
// <editor-fold defaultstate="collapsed" desc="Instantiating">
public static Types instance(Context context) {
@ -120,6 +123,8 @@ public class Types {
messages = JavacMessages.instance(context);
diags = JCDiagnostic.Factory.instance(context);
noWarnings = new Warner(null);
Options options = Options.instance(context);
dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
}
// </editor-fold>
@ -634,12 +639,13 @@ public class Types {
* wraps a diagnostic that can be used to generate more details error
* messages.
*/
public static class FunctionDescriptorLookupError extends RuntimeException {
public static class FunctionDescriptorLookupError extends CompilerInternalException {
private static final long serialVersionUID = 0;
transient JCDiagnostic diagnostic;
FunctionDescriptorLookupError() {
FunctionDescriptorLookupError(boolean dumpStackTraceOnError) {
super(dumpStackTraceOnError);
this.diagnostic = null;
}
@ -651,12 +657,6 @@ public class Types {
public JCDiagnostic getDiagnostic() {
return diagnostic;
}
@Override
public Throwable fillInStackTrace() {
// This is an internal exception; the stack trace is irrelevant.
return this;
}
}
/**
@ -809,7 +809,7 @@ public class Types {
}
FunctionDescriptorLookupError failure(JCDiagnostic diag) {
return new FunctionDescriptorLookupError().setMessage(diag);
return new FunctionDescriptorLookupError(Types.this.dumpStacktraceOnError).setMessage(diag);
}
}
@ -5107,41 +5107,30 @@ public class Types {
// <editor-fold defaultstate="collapsed" desc="Signature Generation">
public abstract static class SignatureGenerator {
public abstract class SignatureGenerator {
public static class InvalidSignatureException extends RuntimeException {
public class InvalidSignatureException extends CompilerInternalException {
private static final long serialVersionUID = 0;
private final transient Type type;
InvalidSignatureException(Type type) {
InvalidSignatureException(Type type, boolean dumpStackTraceOnError) {
super(dumpStackTraceOnError);
this.type = type;
}
public Type type() {
return type;
}
@Override
public Throwable fillInStackTrace() {
// This is an internal exception; the stack trace is irrelevant.
return this;
}
}
private final Types types;
protected abstract void append(char ch);
protected abstract void append(byte[] ba);
protected abstract void append(Name name);
protected void classReference(ClassSymbol c) { /* by default: no-op */ }
protected SignatureGenerator(Types types) {
this.types = types;
}
protected void reportIllegalSignature(Type t) {
throw new InvalidSignatureException(t);
throw new InvalidSignatureException(t, Types.this.dumpStacktraceOnError);
}
/**
@ -5257,9 +5246,9 @@ public class Types {
if (outer.allparams().nonEmpty()) {
boolean rawOuter =
c.owner.kind == MTH || // either a local class
c.name == types.names.empty; // or anonymous
c.name == Types.this.names.empty; // or anonymous
assembleClassSig(rawOuter
? types.erasure(outer)
? Types.this.erasure(outer)
: outer);
append(rawOuter ? '$' : '.');
Assert.check(c.flatname.startsWith(c.owner.enclClass().flatname));
@ -5281,7 +5270,7 @@ public class Types {
for (List<Type> ts = typarams; ts.nonEmpty(); ts = ts.tail) {
Type.TypeVar tvar = (Type.TypeVar) ts.head;
append(tvar.tsym.name);
List<Type> bounds = types.getBounds(tvar);
List<Type> bounds = Types.this.getBounds(tvar);
if ((bounds.head.tsym.flags() & INTERFACE) != 0) {
append(':');
}

View File

@ -47,6 +47,7 @@ import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph;
import com.sun.tools.javac.comp.Infer.GraphSolver.InferenceGraph.Node;
import com.sun.tools.javac.comp.Resolve.InapplicableMethodException;
import com.sun.tools.javac.comp.Resolve.VerboseResolutionMode;
import com.sun.tools.javac.util.CompilerInternalException;
import java.io.IOException;
import java.io.Writer;
@ -68,7 +69,7 @@ import java.util.function.BiPredicate;
import java.util.function.Predicate;
import static com.sun.tools.javac.code.TypeTag.*;
import java.util.Comparator;
import static com.sun.tools.javac.main.Option.DOE;
/** Helper class for type parameter inference, used by the attribution phase.
*
@ -97,6 +98,8 @@ public class Infer {
*/
private List<String> pendingGraphs;
private final boolean dumpStacktraceOnError;
public static Infer instance(Context context) {
Infer instance = context.get(inferKey);
if (instance == null)
@ -119,6 +122,7 @@ public class Infer {
pendingGraphs = List.nil();
emptyContext = new InferenceContext(this, List.nil());
dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
}
/** A value for prototypes that admit any type, including polymorphic ones. */
@ -133,8 +137,8 @@ public class Infer {
transient List<JCDiagnostic> messages = List.nil();
InferenceException() {
super(null);
InferenceException(boolean dumpStacktrace) {
super(null, dumpStacktrace);
}
@Override
@ -144,7 +148,7 @@ public class Infer {
}
InferenceException error(JCDiagnostic diag) {
InferenceException result = new InferenceException();
InferenceException result = new InferenceException(dumpStacktraceOnError);
if (diag != null) {
result.messages = result.messages.append(diag);
}
@ -1342,20 +1346,15 @@ public class Infer {
* A NodeNotFoundException is thrown whenever an inference strategy fails
* to pick the next node to solve in the inference graph.
*/
public static class NodeNotFoundException extends RuntimeException {
class NodeNotFoundException extends CompilerInternalException {
private static final long serialVersionUID = 0;
transient InferenceGraph graph;
public NodeNotFoundException(InferenceGraph graph) {
public NodeNotFoundException(InferenceGraph graph, boolean dumpStacktraceOnError) {
super(dumpStacktraceOnError);
this.graph = graph;
}
@Override
public Throwable fillInStackTrace() {
// This is an internal exception; the stack trace is irrelevant.
return this;
}
}
/**
* Pick the next node (leaf) to solve in the graph
@ -1375,7 +1374,7 @@ public class Infer {
public Node pickNode(InferenceGraph g) {
if (g.nodes.isEmpty()) {
//should not happen
throw new NodeNotFoundException(g);
throw new NodeNotFoundException(g, Infer.this.dumpStacktraceOnError);
}
return g.nodes.get(0);
}
@ -1450,7 +1449,7 @@ public class Infer {
}
if (bestPath == noPath) {
//no path leads there
throw new NodeNotFoundException(g);
throw new NodeNotFoundException(g, Infer.this.dumpStacktraceOnError);
}
return bestPath.fst.head;
}

View File

@ -1796,7 +1796,7 @@ public class LambdaToMethod extends TreeTranslator {
boolean allowIllegalSignatures;
L2MSignatureGenerator(boolean allowIllegalSignatures) {
super(types);
types.super();
this.allowIllegalSignatures = allowIllegalSignatures;
}

View File

@ -62,6 +62,7 @@ import com.sun.tools.javac.tree.JCTree.JCBreak;
import com.sun.tools.javac.tree.JCTree.JCCase;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
import static com.sun.tools.javac.tree.JCTree.JCOperatorExpression.OperandPos.LEFT;
import com.sun.tools.javac.tree.JCTree.JCSwitchExpression;
@ -2629,7 +2630,7 @@ public class Lower extends TreeTranslator {
StringBuilder sb = new StringBuilder();
LowerSignatureGenerator() {
super(types);
types.super();
}
@Override

View File

@ -79,6 +79,7 @@ import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.comp.Resolve.MethodResolutionPhase.*;
import static com.sun.tools.javac.main.Option.DOE;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
import static com.sun.tools.javac.util.Iterators.createCompoundIterator;
@ -112,6 +113,7 @@ public class Resolve {
private final boolean allowYieldStatement;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
final boolean dumpMethodReferenceSearchResults;
final boolean dumpStacktraceOnError;
WriteableScope polymorphicSignatureScope;
@ -149,6 +151,7 @@ public class Resolve {
allowModules = Feature.MODULES.allowedInSource(source);
allowRecords = Feature.RECORDS.allowedInSource(source);
dumpMethodReferenceSearchResults = options.isSet("debug.dumpMethodReferenceSearchResults");
dumpStacktraceOnError = options.isSet("dev") || options.isSet(DOE);
}
/** error symbols, which are returned when resolution fails
@ -584,7 +587,7 @@ public class Resolve {
ForAll pmt = (ForAll) mt;
if (typeargtypes.length() != pmt.tvars.length())
// not enough args
throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length()))));
throw new InapplicableMethodException(diags.fragment(Fragments.WrongNumberTypeArgs(Integer.toString(pmt.tvars.length()))), dumpStacktraceOnError);
// Check type arguments are within bounds
List<Type> formals = pmt.tvars;
List<Type> actuals = typeargtypes;
@ -593,7 +596,7 @@ public class Resolve {
pmt.tvars, typeargtypes);
for (; bounds.nonEmpty(); bounds = bounds.tail) {
if (!types.isSubtypeUnchecked(actuals.head, bounds.head, warn)) {
throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds)));
throw new InapplicableMethodException(diags.fragment(Fragments.ExplicitParamDoNotConformToBounds(actuals.head, bounds)), dumpStacktraceOnError);
}
}
formals = formals.tail;
@ -830,7 +833,7 @@ public class Resolve {
String key = inferDiag ? diag.inferKey : diag.basicKey;
throw inferDiag ?
infer.error(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args)) :
methodCheckFailure.setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
getMethodCheckFailure().setMessage(diags.create(DiagnosticType.FRAGMENT, log.currentSource(), pos, key, args));
}
/**
@ -842,7 +845,7 @@ public class Resolve {
private static final long serialVersionUID = 0;
SharedInapplicableMethodException() {
super(null);
super(null, Resolve.this.dumpStacktraceOnError);
}
SharedInapplicableMethodException setMessage(JCDiagnostic details) {
@ -851,12 +854,15 @@ public class Resolve {
}
}
SharedInapplicableMethodException methodCheckFailure = new SharedInapplicableMethodException();
private SharedInapplicableMethodException methodCheckFailure;
public MethodCheck mostSpecificCheck(List<Type> actuals) {
return nilMethodCheck;
}
private SharedInapplicableMethodException getMethodCheckFailure() {
return methodCheckFailure == null ? methodCheckFailure = new SharedInapplicableMethodException() : methodCheckFailure;
}
}
/**
@ -1036,7 +1042,7 @@ public class Resolve {
}
public void report(DiagnosticPosition pos, JCDiagnostic details) {
throw new InapplicableMethodException(details);
throw new InapplicableMethodException(details, Resolve.this.dumpStacktraceOnError);
}
public Warner checkWarner(DiagnosticPosition pos, Type found, Type req) {
@ -1392,24 +1398,19 @@ public class Resolve {
}
}
public static class InapplicableMethodException extends RuntimeException {
public static class InapplicableMethodException extends CompilerInternalException {
private static final long serialVersionUID = 0;
transient JCDiagnostic diagnostic;
InapplicableMethodException(JCDiagnostic diag) {
InapplicableMethodException(JCDiagnostic diag, boolean dumpStackTraceOnError) {
super(dumpStackTraceOnError);
this.diagnostic = diag;
}
public JCDiagnostic getDiagnostic() {
return diagnostic;
}
@Override
public Throwable fillInStackTrace() {
// This is an internal exception; the stack trace is irrelevant.
return this;
}
}
/* ***************************************************************************

View File

@ -79,6 +79,7 @@ import com.sun.tools.javac.code.Symbol.RecordComponent;
import com.sun.tools.javac.code.Type;
import static com.sun.tools.javac.code.TypeTag.BOT;
import static com.sun.tools.javac.code.TypeTag.VOID;
import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant;
import com.sun.tools.javac.jvm.Target;
import com.sun.tools.javac.tree.JCTree;
@ -786,7 +787,7 @@ public class TransPatterns extends TreeTranslator {
StringBuilder sb = new StringBuilder();
PrimitiveGenerator() {
super(types);
types.super();
}
@Override

View File

@ -100,7 +100,7 @@ public class PoolWriter {
public PoolWriter(Types types, Names names) {
this.types = types;
this.names = names;
this.signatureGen = new SharedSignatureGenerator(types);
this.signatureGen = new SharedSignatureGenerator();
this.pool = new WriteablePoolHelper();
}
@ -278,8 +278,8 @@ public class PoolWriter {
*/
ByteBuffer sigbuf = new ByteBuffer();
SharedSignatureGenerator(Types types) {
super(types);
SharedSignatureGenerator() {
types.super();
}
/**

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.util;
/** The super class of all compiler internal exceptions
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
public class CompilerInternalException extends RuntimeException {
private static final long serialVersionUID = 0;
@SuppressWarnings("this-escape")
public CompilerInternalException(boolean dumpStackTraceOnError) {
/* by default the stacktrace wont be filled, meaning that method CompilerInternalException::fillInStackTrace
* will always be invoked, if we do want to dump the stacktrace then we will invoke super::fillInStackTrace
* there is a bit of a dance here that could be fixed once flexible constructor bodies exits the preview
* state
*/
if (dumpStackTraceOnError) {
super.fillInStackTrace();
}
}
@Override
public Throwable fillInStackTrace() {
return this;
}
}

View File

@ -246,7 +246,7 @@ class TreeDissector {
StringBuilder sb = new StringBuilder();
TDSignatureGenerator(Types types) {
super(types);
types.super();
}
@Override