Mercurial > hg > graal-compiler
changeset 23262:3fa1b7b2329c
added MethodInlineBailoutLimit option to guard against inlining pathologies that effectively prevent compilation from completing in reasonable time
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 06 Jan 2016 18:20:54 +0100 |
parents | 2ea1d1979187 |
children | 75150687d044 |
files | graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java |
diffstat | 2 files changed, 32 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Wed Jan 06 18:06:07 2016 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Wed Jan 06 18:20:54 2016 +0100 @@ -24,6 +24,9 @@ import java.util.Map; +import jdk.vm.ci.code.BailoutException; + +import com.oracle.graal.compiler.common.util.Util; import com.oracle.graal.nodes.Invoke; import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.options.Option; @@ -40,10 +43,16 @@ public static class Options { - // @formatter:off - @Option(help = "Unconditionally inline intrinsics", type = OptionType.Debug) + @Option(help = "Unconditionally inline intrinsics", type = OptionType.Debug)// public static final OptionValue<Boolean> AlwaysInlineIntrinsics = new OptionValue<>(false); - // @formatter:on + + /** + * This is a defensive measure against known pathologies of the inliner where the breadth of + * the inlining call tree exploration can be wide enough to prevent inlining from completing + * in reasonable time. + */ + @Option(help = "Per-compilation method inlining limit before bailing out (use 0 to disable)", type = OptionType.Debug)// + public static final OptionValue<Integer> MethodInlineBailoutLimit = new OptionValue<>(5000); } private final InliningPolicy inliningPolicy; @@ -85,15 +94,21 @@ protected void run(final StructuredGraph graph, final HighTierContext context) { final InliningData data = new InliningData(graph, context, maxMethodPerInlining, canonicalizer, inliningPolicy); + int count = 0; assert data.repOK(); + int limit = Options.MethodInlineBailoutLimit.getValue(); while (data.hasUnprocessedGraphs()) { boolean wasInlined = data.moveForward(); assert data.repOK(); if (wasInlined) { - inliningCount++; + count++; + if (limit > 0 && count == limit) { + throw new BailoutException("Reached method inline limit %d%nInvocation stack:%n %s", limit, Util.join(data.getInvocationStackTrace(), "\n ")); + } } } + inliningCount += count; assert data.inliningDepth() == 0; assert data.graphCount() == 0; }
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Wed Jan 06 18:06:07 2016 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/walker/InliningData.java Wed Jan 06 18:20:54 2016 +0100 @@ -32,6 +32,7 @@ import java.util.BitSet; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Set; import jdk.vm.ci.code.BailoutException; @@ -629,6 +630,18 @@ return result.toString(); } + /** + * Gets a stack trace representing the current inlining stack represented by this object. + */ + public Collection<StackTraceElement> getInvocationStackTrace() { + List<StackTraceElement> result = new ArrayList<>(); + for (CallsiteHolder graph : graphQueue) { + result.add(graph.method().asStackTraceElement(0)); + } + + return result; + } + private boolean contains(StructuredGraph graph) { assert graph != null; for (CallsiteHolder info : graphQueue) {