src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotRetryableCompilation.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotRetryableCompilation.java

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   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 package org.graalvm.compiler.hotspot;
  24 
  25 import static org.graalvm.compiler.debug.Debug.VERBOSE_LEVEL;
  26 import static org.graalvm.compiler.debug.DelegatingDebugConfig.Feature.DUMP_METHOD;
  27 import static org.graalvm.compiler.debug.DelegatingDebugConfig.Level.DUMP;
  28 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.Dump;
  29 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.DumpPath;
  30 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.ForceDebugEnable;
  31 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.PrintCFGFileName;
  32 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.PrintGraphFileName;
  33 
  34 import java.io.ByteArrayOutputStream;
  35 import java.io.File;
  36 import java.io.FileNotFoundException;
  37 import java.io.FileOutputStream;
  38 import java.io.PrintStream;
  39 import java.nio.file.InvalidPathException;
  40 import java.nio.file.Paths;
  41 import java.util.ArrayList;
  42 import java.util.Collection;
  43 
  44 import org.graalvm.compiler.debug.Debug;
  45 import org.graalvm.compiler.debug.DebugDumpHandler;
  46 import org.graalvm.compiler.debug.DebugRetryableTask;
  47 import org.graalvm.compiler.debug.TTY;
  48 import org.graalvm.compiler.options.OptionValues;
  49 import org.graalvm.compiler.printer.GraalDebugConfigCustomizer;
  50 
  51 import jdk.vm.ci.code.BailoutException;
  52 
  53 /**
  54  * Utility for retrying a compilation that throws an exception where the retry enables extra logging
  55  * for subsequently diagnosing the failure.
  56  */
  57 public abstract class HotSpotRetryableCompilation<T> extends DebugRetryableTask<T> {
  58 
  59     protected final OptionValues originalOptions;
  60     protected final HotSpotGraalRuntimeProvider runtime;
  61 
  62     public HotSpotRetryableCompilation(HotSpotGraalRuntimeProvider runtime, OptionValues options) {
  63         this.runtime = runtime;
  64         this.originalOptions = options;
  65     }
  66 
  67     /**
  68      * Gets a value that represents the compilation unit being compiled.
  69      */
  70     @Override
  71     public abstract String toString();
  72 
  73     private static String sanitizedFileName(String name) {
  74         StringBuilder buf = new StringBuilder(name.length());
  75         for (int i = 0; i < name.length(); i++) {
  76             char c = name.charAt(i);
  77             try {
  78                 Paths.get(String.valueOf(c));
  79             } catch (InvalidPathException e) {
  80                 buf.append('_');
  81             }
  82             buf.append(c);
  83         }
  84         return buf.toString();
  85     }
  86 
  87     @Override
  88     protected boolean onRetry(Throwable t) {
  89         if (t instanceof BailoutException) {
  90             return false;
  91         }
  92 
  93         if (!Debug.isEnabled()) {
  94             TTY.printf("Error while compiling %s due to %s.%nRe-run with -D%s%s=true to capture graph dumps upon a compilation failure.%n", this,
  95                             t, HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX, ForceDebugEnable.getName());
  96             return false;
  97         }
  98 
  99         if (Dump.hasBeenSet(originalOptions)) {

 100             // If dumping is explicitly enabled, Graal is being debugged
 101             // so don't interfere with what the user is expecting to see.
 102             return false;
 103         }
 104 
 105         String outputDirectory = runtime.getOutputDirectory();
 106         if (outputDirectory == null) {
 107             return false;
 108         }
 109         String dumpName = sanitizedFileName(toString());
 110         File dumpPath = new File(outputDirectory, dumpName);
 111         dumpPath.mkdirs();
 112         if (!dumpPath.exists()) {
 113             TTY.println("Warning: could not create dump directory " + dumpPath);
 114             return false;
 115         }
 116 
 117         TTY.println("Retrying compilation of " + this + " due to " + t);
 118         retryLogPath = new File(dumpPath, "retry.log").getPath();
 119         log("Exception causing retry", t);
 120         retryDumpHandlers = new ArrayList<>();
 121         retryOptions = new OptionValues(originalOptions,
 122                         PrintCFGFileName, dumpName,
 123                         PrintGraphFileName, dumpName,
 124                         DumpPath, dumpPath.getPath());
 125         override(DUMP, VERBOSE_LEVEL).enable(DUMP_METHOD);
 126         new GraalDebugConfigCustomizer().customize(this);
 127         return true;
 128     }
 129 
 130     private Collection<DebugDumpHandler> retryDumpHandlers;
 131     private OptionValues retryOptions;
 132     private String retryLogPath;
 133 
 134     /**
 135      * Prints a message to a retry log file.
 136      *
 137      * @param message the message to print
 138      * @param t if non-{@code null}, the stack trace for this exception is written to the retry log
 139      *            after {@code message}
 140      */
 141     protected void log(String message, Throwable t) {
 142         if (retryLogPath != null) {
 143             try (PrintStream retryLog = new PrintStream(new FileOutputStream(retryLogPath), true)) {
 144                 StringBuilder buf = new StringBuilder(Thread.currentThread() + ": " + message);
 145                 if (t != null) {
 146                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 147                     t.printStackTrace(new PrintStream(baos));
 148                     buf.append(System.lineSeparator()).append(baos.toString());
 149                 }
 150                 retryLog.println(buf);
 151             } catch (FileNotFoundException e) {
 152                 TTY.println("Warning: could not open retry log file " + retryLogPath + " [" + e + "]");
 153             }
 154         }
 155     }
 156 
 157     @Override
 158     public Collection<DebugDumpHandler> dumpHandlers() {
 159         return retryDumpHandlers;
 160     }
 161 
 162     @Override
 163     public OptionValues getOptions() {
 164         return retryOptions;
 165     }
 166 }


   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   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 package org.graalvm.compiler.hotspot;
  24 
  25 import static org.graalvm.compiler.debug.DebugContext.VERBOSE_LEVEL;
  26 import static org.graalvm.compiler.debug.DebugOptions.Dump;
  27 import static org.graalvm.compiler.debug.DebugOptions.DumpPath;
  28 import static org.graalvm.compiler.debug.DebugOptions.MethodFilter;




  29 
  30 import java.io.ByteArrayOutputStream;
  31 import java.io.File;
  32 import java.io.FileNotFoundException;
  33 import java.io.FileOutputStream;
  34 import java.io.PrintStream;




  35 
  36 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  37 import org.graalvm.compiler.debug.DebugContext;
  38 import org.graalvm.compiler.debug.DebugRetryableTask;
  39 import org.graalvm.compiler.debug.TTY;
  40 import org.graalvm.compiler.options.OptionValues;
  41 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
  42 
  43 import jdk.vm.ci.code.BailoutException;
  44 
  45 /**
  46  * Utility for retrying a compilation that throws an exception where the retry enables extra logging
  47  * for subsequently diagnosing the failure.
  48  */
  49 public abstract class HotSpotRetryableCompilation<T> extends DebugRetryableTask<T> {
  50 

  51     protected final HotSpotGraalRuntimeProvider runtime;
  52 
  53     public HotSpotRetryableCompilation(HotSpotGraalRuntimeProvider runtime) {
  54         this.runtime = runtime;

  55     }
  56 
  57     /**
  58      * Gets a value that represents the compilation unit being compiled.
  59      */
  60     @Override
  61     public abstract String toString();
  62 














  63     @Override
  64     protected DebugContext getRetryContext(DebugContext initialDebug, Throwable t) {
  65         if (t instanceof BailoutException) {
  66             return null;






  67         }
  68 
  69         OptionValues initialOptions = initialDebug.getOptions();
  70         if (Dump.hasBeenSet(initialOptions)) {
  71             // If dumping is explicitly enabled, Graal is being debugged
  72             // so don't interfere with what the user is expecting to see.
  73             return null;
  74         }
  75 
  76         String outputDirectory = runtime.getOutputDirectory();
  77         if (outputDirectory == null) {
  78             return null;
  79         }
  80         String dumpName = GraalDebugHandlersFactory.sanitizedFileName(toString());
  81         File dumpPath = new File(outputDirectory, dumpName);
  82         dumpPath.mkdirs();
  83         if (!dumpPath.exists()) {
  84             TTY.println("Warning: could not create dump directory " + dumpPath);
  85             return null;
  86         }
  87 
  88         TTY.println("Retrying compilation of " + this + " due to " + t);
  89         retryLogPath = new File(dumpPath, "retry.log").getPath();
  90         log("Exception causing retry", t);
  91         OptionValues retryOptions = new OptionValues(initialOptions,
  92                         Dump, ":" + VERBOSE_LEVEL,
  93                         MethodFilter, null,

  94                         DumpPath, dumpPath.getPath());
  95         SnippetReflectionProvider snippetReflection = runtime.getHostProviders().getSnippetReflection();
  96         return DebugContext.create(retryOptions, new GraalDebugHandlersFactory(snippetReflection));

  97     }
  98 


  99     private String retryLogPath;
 100 
 101     /**
 102      * Prints a message to a retry log file.
 103      *
 104      * @param message the message to print
 105      * @param t if non-{@code null}, the stack trace for this exception is written to the retry log
 106      *            after {@code message}
 107      */
 108     protected void log(String message, Throwable t) {
 109         if (retryLogPath != null) {
 110             try (PrintStream retryLog = new PrintStream(new FileOutputStream(retryLogPath), true)) {
 111                 StringBuilder buf = new StringBuilder(Thread.currentThread() + ": " + message);
 112                 if (t != null) {
 113                     ByteArrayOutputStream baos = new ByteArrayOutputStream();
 114                     t.printStackTrace(new PrintStream(baos));
 115                     buf.append(System.lineSeparator()).append(baos.toString());
 116                 }
 117                 retryLog.println(buf);
 118             } catch (FileNotFoundException e) {
 119                 TTY.println("Warning: could not open retry log file " + retryLogPath + " [" + e + "]");
 120             }
 121         }
 122     }










 123 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotRetryableCompilation.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File