< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/CompilationWrapper.java

Print this page




   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 package org.graalvm.compiler.core;
  26 
  27 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
  28 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAction;
  29 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
  30 import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
  31 import static org.graalvm.compiler.core.GraalCompilerOptions.MaxCompilationProblemsPerAction;
  32 import static org.graalvm.compiler.debug.DebugContext.VERBOSE_LEVEL;
  33 import static org.graalvm.compiler.debug.DebugOptions.Dump;
  34 import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
  35 import static org.graalvm.compiler.debug.DebugOptions.MethodFilter;
  36 
  37 import java.io.ByteArrayOutputStream;
  38 import java.io.File;
  39 import java.io.FileOutputStream;
  40 import java.io.IOException;
  41 import java.io.PrintStream;
  42 import java.util.Map;
  43 
  44 import org.graalvm.compiler.debug.DebugContext;
  45 import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
  46 import org.graalvm.compiler.debug.PathUtilities;
  47 import org.graalvm.compiler.debug.TTY;
  48 import org.graalvm.compiler.options.EnumOptionKey;
  49 import org.graalvm.compiler.options.OptionValues;
  50 
  51 import jdk.vm.ci.code.BailoutException;
  52 
  53 /**
  54  * Wrapper for a compilation that centralizes what action to take based on
  55  * {@link GraalCompilerOptions#CompilationBailoutAction} and
  56  * {@link GraalCompilerOptions#CompilationFailureAction} when an uncaught exception occurs during
  57  * compilation.
  58  */
  59 public abstract class CompilationWrapper<T> {
  60 
  61     /**
  62      * Actions to take upon an exception being raised during compilation performed via
  63      * {@link CompilationWrapper}. The actions are with respect to what the user sees on the
  64      * console. The compilation requester determines what ultimate action is taken in
  65      * {@link CompilationWrapper#handleException(Throwable)}.
  66      *
  67      * The actions are in ascending order of verbosity.
  68      */
  69     public enum ExceptionAction {
  70         /**
  71          * Print nothing to the console.
  72          */
  73         Silent,

  74         /**
  75          * Print a stack trace to the console.
  76          */
  77         Print,

  78         /**
  79          * An exception causes the compilation to be retried with extra diagnostics enabled.
  80          */
  81         Diagnose,

  82         /**
  83          * Same as {@link #Diagnose} except that the VM process is exited after retrying.
  84          */
  85         ExitVM;
  86 
  87         private static final ExceptionAction[] VALUES = values();
  88 
  89         /**
  90          * Gets the action that is one level less verbose than this action, bottoming out at the
  91          * least verbose action.
  92          */
  93         ExceptionAction quieter() {
  94             assert ExceptionAction.Silent.ordinal() == 0;
  95             int index = Math.max(ordinal() - 1, 0);
  96             return VALUES[index];
  97         }
  98     }
  99 
 100     private final DiagnosticsOutputDirectory outputDirectory;
 101 


 105      * @param outputDirectory object used to access a directory for dumping if the compilation is
 106      *            re-executed
 107      * @param problemsHandledPerAction map used to count the number of compilation failures or
 108      *            bailouts handled by each action. This is provided by the caller as it is expected
 109      *            to be shared between instances of {@link CompilationWrapper}.
 110      */
 111     public CompilationWrapper(DiagnosticsOutputDirectory outputDirectory, Map<ExceptionAction, Integer> problemsHandledPerAction) {
 112         this.outputDirectory = outputDirectory;
 113         this.problemsHandledPerAction = problemsHandledPerAction;
 114     }
 115 
 116     /**
 117      * Handles an uncaught exception.
 118      *
 119      * @param t an exception thrown during {@link #run(DebugContext)}
 120      * @return a value representing the result of a failed compilation (may be {@code null})
 121      */
 122     protected abstract T handleException(Throwable t);
 123 
 124     /**
 125      * Gets the action to take based on the value of {@code actionKey} in {@code options}.



 126      *
 127      * Subclasses can override this to choose a different action based on factors such as whether
 128      * {@code actionKey} has been explicitly set in {@code options} for example.
 129      *
 130      * @param cause the cause of the bailout or failure
 131      */
 132     protected ExceptionAction lookupAction(OptionValues options, EnumOptionKey<ExceptionAction> actionKey, Throwable cause) {
 133         if (actionKey == CompilationFailureAction) {
 134             if (ExitVMOnException.getValue(options)) {
 135                 assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
 136                 assert ExitVMOnException.getDefaultValue() != true;
 137                 if (CompilationFailureAction.hasBeenSet(options) && CompilationFailureAction.getValue(options) != ExceptionAction.ExitVM) {
 138                     TTY.printf("WARNING: Ignoring %s=%s since %s=true has been explicitly specified.%n",
 139                                     CompilationFailureAction.getName(), CompilationFailureAction.getValue(options),
 140                                     ExitVMOnException.getName());
 141                 }
 142                 return ExceptionAction.ExitVM;
 143             }

 144         }
 145         return actionKey.getValue(options);
 146     }
 147 
 148     /**
 149      * Perform the compilation wrapped by this object.
 150      *
 151      * @param debug the debug context to use for the compilation
 152      */
 153     protected abstract T performCompilation(DebugContext debug);
 154 
 155     /**
 156      * Gets a value that represents the input to the compilation.
 157      */
 158     @Override
 159     public abstract String toString();
 160 
 161     /**
 162      * Creates the {@link DebugContext} to use when retrying a compilation.
 163      *
 164      * @param options the options for configuring the debug context
 165      * @param logStream the log stream to use in the debug context
 166      */
 167     protected abstract DebugContext createRetryDebugContext(OptionValues options, PrintStream logStream);
 168 
 169     @SuppressWarnings("try")
 170     public final T run(DebugContext initialDebug) {
 171         try {
 172             return performCompilation(initialDebug);
 173         } catch (Throwable cause) {
 174             OptionValues initialOptions = initialDebug.getOptions();
 175 
 176             String causeType = "failure";
 177             EnumOptionKey<ExceptionAction> actionKey;
 178             if (cause instanceof BailoutException) {
 179                 actionKey = CompilationBailoutAction;
 180                 causeType = "bailout";
 181             } else {
 182                 actionKey = CompilationFailureAction;
 183                 causeType = "failure";
 184             }
 185             synchronized (CompilationFailureAction) {
 186                 // Serialize all compilation failure handling.
 187                 // This prevents retry compilation storms and interleaving
 188                 // of compilation exception messages.
 189                 // It also allows for reliable testing of CompilationWrapper
 190                 // by avoiding a race whereby retry compilation output from a
 191                 // forced crash (i.e., use of GraalCompilerOptions.CrashAt)
 192                 // is truncated.
 193 
 194                 ExceptionAction action = lookupAction(initialOptions, actionKey, cause);
 195 
 196                 action = adjustAction(initialOptions, actionKey, action);
 197 
 198                 if (action == ExceptionAction.Silent) {
 199                     return handleException(cause);
 200                 }
 201 
 202                 if (action == ExceptionAction.Print) {
 203                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 204                     try (PrintStream ps = new PrintStream(baos)) {
 205                         ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
 206                         cause.printStackTrace(ps);
 207                         ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
 208                                         causeType,
 209                                         actionKey.getName(), ExceptionAction.Silent,
 210                                         actionKey.getName(), ExceptionAction.Silent);
 211                         ps.printf("To capture more information for diagnosing or reporting a compilation %s, " +
 212                                         "set %s to %s or %s (e.g., -Dgraal.%s=%s).%n",
 213                                         causeType,
 214                                         actionKey.getName(), ExceptionAction.Diagnose,
 215                                         ExceptionAction.ExitVM,
 216                                         actionKey.getName(), ExceptionAction.Diagnose);
 217                     }
 218                     TTY.print(baos.toString());
 219                     return handleException(cause);
 220                 }
 221 
 222                 // action is Diagnose or ExitVM
 223 
 224                 if (Dump.hasBeenSet(initialOptions)) {
 225                     // If dumping is explicitly enabled, Graal is being debugged
 226                     // so don't interfere with what the user is expecting to see.
 227                     return handleException(cause);
 228                 }
 229 
 230                 File dumpPath = null;
 231                 try {
 232                     String dir = this.outputDirectory.getPath();
 233                     if (dir != null) {
 234                         String dumpName = PathUtilities.sanitizeFileName(toString());
 235                         dumpPath = new File(dir, dumpName);
 236                         dumpPath.mkdirs();
 237                         if (!dumpPath.exists()) {
 238                             TTY.println("Warning: could not create diagnostics directory " + dumpPath);
 239                             dumpPath = null;
 240                         }
 241                     }
 242                 } catch (Throwable t) {
 243                     TTY.println("Warning: could not create Graal diagnostic directory");
 244                     t.printStackTrace(TTY.out);
 245                 }
 246 
 247                 String message;
 248                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 249                 try (PrintStream ps = new PrintStream(baos)) {
 250                     ps.printf("%s: Compilation of %s failed:%n", Thread.currentThread(), this);
 251                     cause.printStackTrace(ps);
 252                     ps.printf("To disable compilation %s notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
 253                                     causeType,
 254                                     actionKey.getName(), ExceptionAction.Silent,
 255                                     actionKey.getName(), ExceptionAction.Silent);
 256                     ps.printf("To print a message for a compilation %s without retrying the compilation, " +
 257                                     "set %s to %s (e.g., -Dgraal.%s=%s).%n",
 258                                     causeType,
 259                                     actionKey.getName(), ExceptionAction.Print,
 260                                     actionKey.getName(), ExceptionAction.Print);
 261                     if (dumpPath != null) {
 262                         ps.println("Retrying compilation of " + this);
 263                     } else {
 264                         ps.println("Not retrying compilation of " + this + " as the dump path could not be created.");
 265                     }
 266                     message = baos.toString();
 267                 }
 268 
 269                 TTY.print(message);
 270                 if (dumpPath == null) {
 271                     return handleException(cause);
 272                 }
 273 
 274                 File retryLogFile = new File(dumpPath, "retry.log");
 275                 try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) {
 276                     ps.print(message);
 277                 } catch (IOException ioe) {
 278                     TTY.printf("Error writing to %s: %s%n", retryLogFile, ioe);
 279                 }
 280 


 303                         fos.write(logBaos.toByteArray());
 304                     } catch (Throwable e) {
 305                         TTY.printf("Error writing to %s: %s%n", retryLogFile, e);
 306                     }
 307                 }
 308             }
 309         }
 310     }
 311 
 312     private void maybeExitVM(ExceptionAction action) {
 313         if (action == ExitVM) {
 314             TTY.println("Exiting VM after retry compilation of " + this);
 315             System.exit(-1);
 316         }
 317     }
 318 
 319     /**
 320      * Adjusts {@code initialAction} if necessary based on
 321      * {@link GraalCompilerOptions#MaxCompilationProblemsPerAction}.
 322      */
 323     private ExceptionAction adjustAction(OptionValues initialOptions, EnumOptionKey<ExceptionAction> actionKey, ExceptionAction initialAction) {
 324         ExceptionAction action = initialAction;
 325         int maxProblems = MaxCompilationProblemsPerAction.getValue(initialOptions);
 326         if (action != ExceptionAction.ExitVM) {
 327             synchronized (problemsHandledPerAction) {
 328                 while (action != ExceptionAction.Silent) {
 329                     int problems = problemsHandledPerAction.getOrDefault(action, 0);
 330                     if (problems >= maxProblems) {
 331                         if (problems == maxProblems) {
 332                             TTY.printf("Warning: adjusting %s from %s to %s after %s (%d) failed compilations%n", actionKey, action, action.quieter(),
 333                                             MaxCompilationProblemsPerAction, maxProblems);
 334                             // Ensure that the message above is only printed once
 335                             problemsHandledPerAction.put(action, problems + 1);
 336                         }
 337                         action = action.quieter();
 338                     } else {
 339                         break;
 340                     }
 341                 }
 342                 problemsHandledPerAction.put(action, problemsHandledPerAction.getOrDefault(action, 0) + 1);
 343             }
 344         }
 345         return action;
 346     }
 347 }


   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 
  25 package org.graalvm.compiler.core;
  26 
  27 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
  28 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
  29 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
  30 import static org.graalvm.compiler.core.GraalCompilerOptions.ExitVMOnException;
  31 import static org.graalvm.compiler.core.GraalCompilerOptions.MaxCompilationProblemsPerAction;
  32 import static org.graalvm.compiler.debug.DebugContext.VERBOSE_LEVEL;
  33 import static org.graalvm.compiler.debug.DebugOptions.Dump;
  34 import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
  35 import static org.graalvm.compiler.debug.DebugOptions.MethodFilter;
  36 
  37 import java.io.ByteArrayOutputStream;
  38 import java.io.File;
  39 import java.io.FileOutputStream;
  40 import java.io.IOException;
  41 import java.io.PrintStream;
  42 import java.util.Map;
  43 
  44 import org.graalvm.compiler.debug.DebugContext;
  45 import org.graalvm.compiler.debug.DiagnosticsOutputDirectory;
  46 import org.graalvm.compiler.debug.PathUtilities;
  47 import org.graalvm.compiler.debug.TTY;

  48 import org.graalvm.compiler.options.OptionValues;
  49 
  50 import jdk.vm.ci.code.BailoutException;
  51 
  52 /**
  53  * Wrapper for a compilation that centralizes what action to take based on
  54  * {@link GraalCompilerOptions#CompilationBailoutAsFailure} and
  55  * {@link GraalCompilerOptions#CompilationFailureAction} when an uncaught exception occurs during
  56  * compilation.
  57  */
  58 public abstract class CompilationWrapper<T> {
  59 
  60     /**
  61      * Actions to take upon an exception being raised during compilation performed via
  62      * {@link CompilationWrapper}. The actions are with respect to what the user sees on the
  63      * console. The compilation requester determines what ultimate action is taken in
  64      * {@link CompilationWrapper#handleException(Throwable)}.
  65      *
  66      * The actions are in ascending order of verbosity.
  67      */
  68     public enum ExceptionAction {
  69         /**
  70          * Print nothing to the console.
  71          */
  72         Silent,
  73 
  74         /**
  75          * Print a stack trace to the console.
  76          */
  77         Print,
  78 
  79         /**
  80          * An exception causes the compilation to be retried with extra diagnostics enabled.
  81          */
  82         Diagnose,
  83 
  84         /**
  85          * Same as {@link #Diagnose} except that the VM process is exited after retrying.
  86          */
  87         ExitVM;
  88 
  89         private static final ExceptionAction[] VALUES = values();
  90 
  91         /**
  92          * Gets the action that is one level less verbose than this action, bottoming out at the
  93          * least verbose action.
  94          */
  95         ExceptionAction quieter() {
  96             assert ExceptionAction.Silent.ordinal() == 0;
  97             int index = Math.max(ordinal() - 1, 0);
  98             return VALUES[index];
  99         }
 100     }
 101 
 102     private final DiagnosticsOutputDirectory outputDirectory;
 103 


 107      * @param outputDirectory object used to access a directory for dumping if the compilation is
 108      *            re-executed
 109      * @param problemsHandledPerAction map used to count the number of compilation failures or
 110      *            bailouts handled by each action. This is provided by the caller as it is expected
 111      *            to be shared between instances of {@link CompilationWrapper}.
 112      */
 113     public CompilationWrapper(DiagnosticsOutputDirectory outputDirectory, Map<ExceptionAction, Integer> problemsHandledPerAction) {
 114         this.outputDirectory = outputDirectory;
 115         this.problemsHandledPerAction = problemsHandledPerAction;
 116     }
 117 
 118     /**
 119      * Handles an uncaught exception.
 120      *
 121      * @param t an exception thrown during {@link #run(DebugContext)}
 122      * @return a value representing the result of a failed compilation (may be {@code null})
 123      */
 124     protected abstract T handleException(Throwable t);
 125 
 126     /**
 127      * Gets the action to take based on the value of
 128      * {@link GraalCompilerOptions#CompilationBailoutAsFailure},
 129      * {@link GraalCompilerOptions#CompilationFailureAction} and
 130      * {@link GraalCompilerOptions#ExitVMOnException} in {@code options}.
 131      *
 132      * Subclasses can override this to choose a different action.

 133      *
 134      * @param cause the cause of the bailout or failure
 135      */
 136     protected ExceptionAction lookupAction(OptionValues options, Throwable cause) {
 137         if (cause instanceof BailoutException && !CompilationBailoutAsFailure.getValue(options)) {
 138             return ExceptionAction.Silent;
 139         }
 140         if (ExitVMOnException.getValue(options)) {
 141             assert CompilationFailureAction.getDefaultValue() != ExceptionAction.ExitVM;
 142             assert ExitVMOnException.getDefaultValue() != true;
 143             if (CompilationFailureAction.hasBeenSet(options) && CompilationFailureAction.getValue(options) != ExceptionAction.ExitVM) {
 144                 TTY.printf("WARNING: Ignoring %s=%s since %s=true has been explicitly specified.%n",
 145                                 CompilationFailureAction.getName(), CompilationFailureAction.getValue(options),
 146                                 ExitVMOnException.getName());
 147             }
 148             return ExceptionAction.ExitVM;
 149         }
 150         return CompilationFailureAction.getValue(options);
 151     }
 152 
 153     /**
 154      * Perform the compilation wrapped by this object.
 155      *
 156      * @param debug the debug context to use for the compilation
 157      */
 158     protected abstract T performCompilation(DebugContext debug);
 159 
 160     /**
 161      * Gets a value that represents the input to the compilation.
 162      */
 163     @Override
 164     public abstract String toString();
 165 
 166     /**
 167      * Creates the {@link DebugContext} to use when retrying a compilation.
 168      *
 169      * @param options the options for configuring the debug context
 170      * @param logStream the log stream to use in the debug context
 171      */
 172     protected abstract DebugContext createRetryDebugContext(OptionValues options, PrintStream logStream);
 173 
 174     @SuppressWarnings("try")
 175     public final T run(DebugContext initialDebug) {
 176         try {
 177             return performCompilation(initialDebug);
 178         } catch (Throwable cause) {
 179             OptionValues initialOptions = initialDebug.getOptions();
 180 









 181             synchronized (CompilationFailureAction) {
 182                 // Serialize all compilation failure handling.
 183                 // This prevents retry compilation storms and interleaving
 184                 // of compilation exception messages.
 185                 // It also allows for reliable testing of CompilationWrapper
 186                 // by avoiding a race whereby retry compilation output from a
 187                 // forced crash (i.e., use of GraalCompilerOptions.CrashAt)
 188                 // is truncated.
 189 
 190                 ExceptionAction action = lookupAction(initialOptions, cause);
 191 
 192                 action = adjustAction(initialOptions, action);
 193 
 194                 if (action == ExceptionAction.Silent) {
 195                     return handleException(cause);
 196                 }
 197 
 198                 if (action == ExceptionAction.Print) {
 199                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 200                     try (PrintStream ps = new PrintStream(baos)) {
 201                         ps.printf("%s: Compilation of %s failed: ", Thread.currentThread(), this);
 202                         cause.printStackTrace(ps);
 203                         ps.printf("To disable compilation failure notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
 204                                         CompilationFailureAction.getName(), ExceptionAction.Silent,
 205                                         CompilationFailureAction.getName(), ExceptionAction.Silent);
 206                         ps.printf("To capture more information for diagnosing or reporting a compilation failure, " +

 207                                         "set %s to %s or %s (e.g., -Dgraal.%s=%s).%n",
 208                                         CompilationFailureAction.getName(), ExceptionAction.Diagnose,

 209                                         ExceptionAction.ExitVM,
 210                                         CompilationFailureAction.getName(), ExceptionAction.Diagnose);
 211                     }
 212                     TTY.print(baos.toString());
 213                     return handleException(cause);
 214                 }
 215 
 216                 // action is Diagnose or ExitVM
 217 
 218                 if (Dump.hasBeenSet(initialOptions)) {
 219                     // If dumping is explicitly enabled, Graal is being debugged
 220                     // so don't interfere with what the user is expecting to see.
 221                     return handleException(cause);
 222                 }
 223 
 224                 File dumpPath = null;
 225                 try {
 226                     String dir = this.outputDirectory.getPath();
 227                     if (dir != null) {
 228                         String dumpName = PathUtilities.sanitizeFileName(toString());
 229                         dumpPath = new File(dir, dumpName);
 230                         dumpPath.mkdirs();
 231                         if (!dumpPath.exists()) {
 232                             TTY.println("Warning: could not create diagnostics directory " + dumpPath);
 233                             dumpPath = null;
 234                         }
 235                     }
 236                 } catch (Throwable t) {
 237                     TTY.println("Warning: could not create Graal diagnostic directory");
 238                     t.printStackTrace(TTY.out);
 239                 }
 240 
 241                 String message;
 242                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 243                 try (PrintStream ps = new PrintStream(baos)) {
 244                     ps.printf("%s: Compilation of %s failed:%n", Thread.currentThread(), this);
 245                     cause.printStackTrace(ps);
 246                     ps.printf("To disable compilation failure notifications, set %s to %s (e.g., -Dgraal.%s=%s).%n",
 247                                     CompilationFailureAction.getName(), ExceptionAction.Silent,
 248                                     CompilationFailureAction.getName(), ExceptionAction.Silent);
 249                     ps.printf("To print a message for a compilation failure without retrying the compilation, " +

 250                                     "set %s to %s (e.g., -Dgraal.%s=%s).%n",
 251                                     CompilationFailureAction.getName(), ExceptionAction.Print,
 252                                     CompilationFailureAction.getName(), ExceptionAction.Print);

 253                     if (dumpPath != null) {
 254                         ps.println("Retrying compilation of " + this);
 255                     } else {
 256                         ps.println("Not retrying compilation of " + this + " as the dump path could not be created.");
 257                     }
 258                     message = baos.toString();
 259                 }
 260 
 261                 TTY.print(message);
 262                 if (dumpPath == null) {
 263                     return handleException(cause);
 264                 }
 265 
 266                 File retryLogFile = new File(dumpPath, "retry.log");
 267                 try (PrintStream ps = new PrintStream(new FileOutputStream(retryLogFile))) {
 268                     ps.print(message);
 269                 } catch (IOException ioe) {
 270                     TTY.printf("Error writing to %s: %s%n", retryLogFile, ioe);
 271                 }
 272 


 295                         fos.write(logBaos.toByteArray());
 296                     } catch (Throwable e) {
 297                         TTY.printf("Error writing to %s: %s%n", retryLogFile, e);
 298                     }
 299                 }
 300             }
 301         }
 302     }
 303 
 304     private void maybeExitVM(ExceptionAction action) {
 305         if (action == ExitVM) {
 306             TTY.println("Exiting VM after retry compilation of " + this);
 307             System.exit(-1);
 308         }
 309     }
 310 
 311     /**
 312      * Adjusts {@code initialAction} if necessary based on
 313      * {@link GraalCompilerOptions#MaxCompilationProblemsPerAction}.
 314      */
 315     private ExceptionAction adjustAction(OptionValues initialOptions, ExceptionAction initialAction) {
 316         ExceptionAction action = initialAction;
 317         int maxProblems = MaxCompilationProblemsPerAction.getValue(initialOptions);
 318         if (action != ExceptionAction.ExitVM) {
 319             synchronized (problemsHandledPerAction) {
 320                 while (action != ExceptionAction.Silent) {
 321                     int problems = problemsHandledPerAction.getOrDefault(action, 0);
 322                     if (problems >= maxProblems) {
 323                         if (problems == maxProblems) {
 324                             TTY.printf("Warning: adjusting %s from %s to %s after %s (%d) failed compilations%n", CompilationFailureAction, action, action.quieter(),
 325                                             MaxCompilationProblemsPerAction, maxProblems);
 326                             // Ensure that the message above is only printed once
 327                             problemsHandledPerAction.put(action, problems + 1);
 328                         }
 329                         action = action.quieter();
 330                     } else {
 331                         break;
 332                     }
 333                 }
 334                 problemsHandledPerAction.put(action, problemsHandledPerAction.getOrDefault(action, 0) + 1);
 335             }
 336         }
 337         return action;
 338     }
 339 }
< prev index next >