< prev index next >

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

Print this page




  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.hotspot;
  26 
  27 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Diagnose;
  28 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
  29 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
  30 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
  31 import static org.graalvm.compiler.core.phases.HighTier.Options.Inline;
  32 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
  33 
  34 import java.io.PrintStream;
  35 import java.util.List;
  36 
  37 import jdk.internal.vm.compiler.collections.EconomicMap;
  38 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  39 import org.graalvm.compiler.code.CompilationResult;
  40 import org.graalvm.compiler.core.CompilationPrinter;
  41 import org.graalvm.compiler.core.CompilationWrapper;
  42 import org.graalvm.compiler.core.common.CompilationIdentifier;
  43 import org.graalvm.compiler.debug.CounterKey;
  44 import org.graalvm.compiler.debug.DebugCloseable;
  45 import org.graalvm.compiler.debug.DebugContext;
  46 import org.graalvm.compiler.debug.DebugDumpScope;
  47 import org.graalvm.compiler.debug.GraalError;
  48 import org.graalvm.compiler.debug.TimerKey;
  49 import org.graalvm.compiler.options.OptionKey;
  50 import org.graalvm.compiler.options.OptionValues;
  51 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
  52 
  53 import jdk.vm.ci.code.BailoutException;
  54 import jdk.vm.ci.code.CodeCacheProvider;
  55 import jdk.vm.ci.hotspot.EventProvider;
  56 import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
  57 import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
  58 import jdk.vm.ci.hotspot.HotSpotInstalledCode;
  59 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
  60 import jdk.vm.ci.hotspot.HotSpotNmethod;
  61 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
  62 import jdk.vm.ci.runtime.JVMCICompiler;
  63 import jdk.vm.ci.services.JVMCIServiceLocator;
  64 
  65 public class CompilationTask {
  66 
  67     private static final EventProvider eventProvider;
  68 
  69     static {
  70         List<EventProvider> providers = JVMCIServiceLocator.getProviders(EventProvider.class);
  71         if (providers.size() > 1) {
  72             throw new GraalError("Multiple %s providers found: %s", EventProvider.class.getName(), providers);
  73         } else if (providers.isEmpty()) {
  74             eventProvider = EventProvider.createEmptyEventProvider();
  75         } else {
  76             eventProvider = providers.get(0);
  77         }
  78     }
  79 
  80     private final HotSpotJVMCIRuntime jvmciRuntime;
  81 
  82     private final HotSpotGraalCompiler compiler;
  83     private final HotSpotCompilationIdentifier compilationId;
  84 
  85     private HotSpotInstalledCode installedCode;
  86 
  87     /**
  88      * Specifies whether the compilation result is installed as the
  89      * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method.
  90      */
  91     private final boolean installAsDefault;
  92 
  93     private final boolean useProfilingInfo;
  94     private final boolean shouldRetainLocalVariables;
  95 
  96     final class HotSpotCompilationWrapper extends CompilationWrapper<HotSpotCompilationRequestResult> {
  97         private final EventProvider.CompilationEvent compilationEvent;
  98         CompilationResult result;
  99 
 100         HotSpotCompilationWrapper(EventProvider.CompilationEvent compilationEvent) {
 101             super(compiler.getGraalRuntime().getOutputDirectory(), compiler.getGraalRuntime().getCompilationProblemsPerAction());
 102             this.compilationEvent = compilationEvent;
 103         }
 104 
 105         @Override
 106         protected DebugContext createRetryDebugContext(OptionValues retryOptions, PrintStream logStream) {
 107             SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
 108             return DebugContext.create(retryOptions, logStream, new GraalDebugHandlersFactory(snippetReflection));
 109         }
 110 
 111         @Override
 112         public String toString() {
 113             return getMethod().format("%H.%n(%p)");
 114         }
 115 
 116         @Override
 117         protected HotSpotCompilationRequestResult handleException(Throwable t) {
 118             if (t instanceof BailoutException) {
 119                 BailoutException bailout = (BailoutException) t;
 120                 /*
 121                  * Handling of permanent bailouts: Permanent bailouts that can happen for example
 122                  * due to unsupported unstructured control flow in the bytecodes of a method must
 123                  * not be retried. Hotspot compile broker will ensure that no recompilation at the
 124                  * given tier will happen if retry is false.
 125                  */
 126                 return HotSpotCompilationRequestResult.failure(bailout.getMessage(), !bailout.isPermanent());
 127             }
 128             // Log a failure event.
 129             EventProvider.CompilerFailureEvent event = eventProvider.newCompilerFailureEvent();
 130             if (event.shouldWrite()) {
 131                 event.setCompileId(getId());
 132                 event.setMessage(t.getMessage());
 133                 event.commit();
 134             }
 135 
 136             /*
 137              * Treat random exceptions from the compiler as indicating a problem compiling this
 138              * method. Report the result of toString instead of getMessage to ensure that the
 139              * exception type is included in the output in case there's no detail mesage.
 140              */
 141             return HotSpotCompilationRequestResult.failure(t.toString(), false);
 142         }
 143 
 144         @Override
 145         protected ExceptionAction lookupAction(OptionValues values, Throwable cause) {
 146             if (cause instanceof BailoutException) {
 147                 BailoutException bailout = (BailoutException) cause;
 148                 if (bailout.isPermanent()) {
 149                     // Respect current action if it has been explicitly set.
 150                     if (!CompilationBailoutAsFailure.hasBeenSet(values)) {
 151                         // Get more info for permanent bailouts during bootstrap.
 152                         if (compiler.getGraalRuntime().isBootstrapping()) {
 153                             return Diagnose;
 154                         }


 164             if (!CompilationFailureAction.hasBeenSet(values)) {
 165                 // Automatically exit on failure during bootstrap.
 166                 if (compiler.getGraalRuntime().isBootstrapping()) {
 167                     return ExitVM;
 168                 }
 169             }
 170             return super.lookupAction(values, cause);
 171         }
 172 
 173         @SuppressWarnings("try")
 174         @Override
 175         protected HotSpotCompilationRequestResult performCompilation(DebugContext debug) {
 176             HotSpotResolvedJavaMethod method = getMethod();
 177             int entryBCI = getEntryBCI();
 178             final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
 179             CompilationStatistics stats = CompilationStatistics.create(debug.getOptions(), method, isOSR);
 180 
 181             final CompilationPrinter printer = CompilationPrinter.begin(debug.getOptions(), compilationId, method, entryBCI);
 182 
 183             try (DebugContext.Scope s = debug.scope("Compiling", new DebugDumpScope(getIdString(), true))) {
 184                 // Begin the compilation event.
 185                 compilationEvent.begin();
 186                 result = compiler.compile(method, entryBCI, useProfilingInfo, shouldRetainLocalVariables, compilationId, debug);
 187             } catch (Throwable e) {
 188                 throw debug.handle(e);
 189             } finally {
 190                 // End the compilation event.
 191                 compilationEvent.end();
 192             }
 193 
 194             if (result != null) {
 195                 try (DebugCloseable b = CodeInstallationTime.start(debug)) {
 196                     installMethod(debug, result);
 197                 }
 198                 // Installation is included in compilation time and memory usage reported by printer
 199                 printer.finish(result);
 200             }
 201             stats.finish(method, installedCode);
 202             if (result != null) {
 203                 return HotSpotCompilationRequestResult.success(result.getBytecodeSize() - method.getCodeSize());
 204             }
 205             return null;
 206         }
 207 
 208     }
 209 
 210     public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault) {
 211         this(jvmciRuntime, compiler, request, useProfilingInfo, false, installAsDefault);


 305      * Time spent in code installation.
 306      */
 307     public static final TimerKey CodeInstallationTime = DebugContext.timer("CodeInstallation");
 308 
 309     public HotSpotCompilationRequestResult runCompilation(OptionValues initialOptions) {
 310         OptionValues options = filterOptions(initialOptions);
 311         SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
 312         try (DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(snippetReflection))) {
 313             return runCompilation(debug);
 314         }
 315     }
 316 
 317     @SuppressWarnings("try")
 318     public HotSpotCompilationRequestResult runCompilation(DebugContext debug) {
 319         HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
 320         GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
 321         int entryBCI = getEntryBCI();
 322         boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
 323         HotSpotResolvedJavaMethod method = getMethod();
 324 
 325         // Log a compilation event.
 326         EventProvider.CompilationEvent compilationEvent = eventProvider.newCompilationEvent();
 327 
 328         if (installAsDefault || isOSR) {
 329             // If there is already compiled code for this method on our level we simply return.
 330             // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
 331             // only need to check for that value.
 332             if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) {
 333                 return HotSpotCompilationRequestResult.failure("Already compiled", false);
 334             }
 335             if (HotSpotGraalCompilerFactory.shouldExclude(method)) {
 336                 return HotSpotCompilationRequestResult.failure("GraalCompileOnly excluded", false);
 337             }
 338         }
 339 
 340         HotSpotCompilationWrapper compilation = new HotSpotCompilationWrapper(compilationEvent);
 341         try (DebugCloseable a = CompilationTime.start(debug)) {
 342             return compilation.run(debug);
 343         } finally {
 344             try {
 345                 int compiledBytecodes = 0;
 346                 int codeSize = 0;
 347 
 348                 if (compilation.result != null) {
 349                     compiledBytecodes = compilation.result.getBytecodeSize();
 350                     CompiledBytecodes.add(debug, compiledBytecodes);
 351                     if (installedCode != null) {
 352                         codeSize = installedCode.getSize();
 353                         CompiledAndInstalledBytecodes.add(debug, compiledBytecodes);
 354                         InstalledCodeSize.add(debug, codeSize);
 355                     }
 356                 }
 357 
 358                 // Log a compilation event.
 359                 if (compilationEvent.shouldWrite()) {
 360                     compilationEvent.setMethod(method.format("%H.%n(%p)"));
 361                     compilationEvent.setCompileId(getId());
 362                     compilationEvent.setCompileLevel(config.compilationLevelFullOptimization);
 363                     compilationEvent.setSucceeded(compilation.result != null && installedCode != null);
 364                     compilationEvent.setIsOsr(isOSR);
 365                     compilationEvent.setCodeSize(codeSize);
 366                     compilationEvent.setInlinedBytes(compiledBytecodes);
 367                     compilationEvent.commit();
 368                 }
 369             } catch (Throwable t) {
 370                 return compilation.handleException(t);
 371             }
 372         }
 373     }
 374 
 375     @SuppressWarnings("try")
 376     private void installMethod(DebugContext debug, final CompilationResult compResult) {
 377         final CodeCacheProvider codeCache = jvmciRuntime.getHostJVMCIBackend().getCodeCache();
 378         HotSpotBackend backend = compiler.getGraalRuntime().getHostBackend();
 379         installedCode = null;
 380         Object[] context = {new DebugDumpScope(getIdString(), true), codeCache, getMethod(), compResult};
 381         try (DebugContext.Scope s = debug.scope("CodeInstall", context)) {
 382             HotSpotCompilationRequest request = getRequest();
 383             installedCode = (HotSpotInstalledCode) backend.createInstalledCode(debug,
 384                             request.getMethod(),
 385                             request,
 386                             compResult,
 387                             null,


  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.hotspot;
  26 
  27 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.Diagnose;
  28 import static org.graalvm.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
  29 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
  30 import static org.graalvm.compiler.core.GraalCompilerOptions.CompilationFailureAction;
  31 import static org.graalvm.compiler.core.phases.HighTier.Options.Inline;
  32 import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
  33 
  34 import java.io.PrintStream;

  35 
  36 import jdk.internal.vm.compiler.collections.EconomicMap;
  37 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
  38 import org.graalvm.compiler.code.CompilationResult;
  39 import org.graalvm.compiler.core.CompilationPrinter;
  40 import org.graalvm.compiler.core.CompilationWrapper;
  41 import org.graalvm.compiler.core.common.CompilationIdentifier;
  42 import org.graalvm.compiler.debug.CounterKey;
  43 import org.graalvm.compiler.debug.DebugCloseable;
  44 import org.graalvm.compiler.debug.DebugContext;
  45 import org.graalvm.compiler.debug.DebugDumpScope;

  46 import org.graalvm.compiler.debug.TimerKey;
  47 import org.graalvm.compiler.options.OptionKey;
  48 import org.graalvm.compiler.options.OptionValues;
  49 import org.graalvm.compiler.printer.GraalDebugHandlersFactory;
  50 
  51 import jdk.vm.ci.code.BailoutException;
  52 import jdk.vm.ci.code.CodeCacheProvider;

  53 import jdk.vm.ci.hotspot.HotSpotCompilationRequest;
  54 import jdk.vm.ci.hotspot.HotSpotCompilationRequestResult;
  55 import jdk.vm.ci.hotspot.HotSpotInstalledCode;
  56 import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime;
  57 import jdk.vm.ci.hotspot.HotSpotNmethod;
  58 import jdk.vm.ci.hotspot.HotSpotResolvedJavaMethod;
  59 import jdk.vm.ci.runtime.JVMCICompiler;

  60 
  61 public class CompilationTask {
  62 













  63     private final HotSpotJVMCIRuntime jvmciRuntime;
  64 
  65     private final HotSpotGraalCompiler compiler;
  66     private final HotSpotCompilationIdentifier compilationId;
  67 
  68     private HotSpotInstalledCode installedCode;
  69 
  70     /**
  71      * Specifies whether the compilation result is installed as the
  72      * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method.
  73      */
  74     private final boolean installAsDefault;
  75 
  76     private final boolean useProfilingInfo;
  77     private final boolean shouldRetainLocalVariables;
  78 
  79     final class HotSpotCompilationWrapper extends CompilationWrapper<HotSpotCompilationRequestResult> {

  80         CompilationResult result;
  81 
  82         HotSpotCompilationWrapper() {
  83             super(compiler.getGraalRuntime().getOutputDirectory(), compiler.getGraalRuntime().getCompilationProblemsPerAction());

  84         }
  85 
  86         @Override
  87         protected DebugContext createRetryDebugContext(OptionValues retryOptions, PrintStream logStream) {
  88             SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
  89             return DebugContext.create(retryOptions, logStream, new GraalDebugHandlersFactory(snippetReflection));
  90         }
  91 
  92         @Override
  93         public String toString() {
  94             return getMethod().format("%H.%n(%p)");
  95         }
  96 
  97         @Override
  98         protected HotSpotCompilationRequestResult handleException(Throwable t) {
  99             if (t instanceof BailoutException) {
 100                 BailoutException bailout = (BailoutException) t;
 101                 /*
 102                  * Handling of permanent bailouts: Permanent bailouts that can happen for example
 103                  * due to unsupported unstructured control flow in the bytecodes of a method must
 104                  * not be retried. Hotspot compile broker will ensure that no recompilation at the
 105                  * given tier will happen if retry is false.
 106                  */
 107                 return HotSpotCompilationRequestResult.failure(bailout.getMessage(), !bailout.isPermanent());
 108             }







 109 
 110             /*
 111              * Treat random exceptions from the compiler as indicating a problem compiling this
 112              * method. Report the result of toString instead of getMessage to ensure that the
 113              * exception type is included in the output in case there's no detail mesage.
 114              */
 115             return HotSpotCompilationRequestResult.failure(t.toString(), false);
 116         }
 117 
 118         @Override
 119         protected ExceptionAction lookupAction(OptionValues values, Throwable cause) {
 120             if (cause instanceof BailoutException) {
 121                 BailoutException bailout = (BailoutException) cause;
 122                 if (bailout.isPermanent()) {
 123                     // Respect current action if it has been explicitly set.
 124                     if (!CompilationBailoutAsFailure.hasBeenSet(values)) {
 125                         // Get more info for permanent bailouts during bootstrap.
 126                         if (compiler.getGraalRuntime().isBootstrapping()) {
 127                             return Diagnose;
 128                         }


 138             if (!CompilationFailureAction.hasBeenSet(values)) {
 139                 // Automatically exit on failure during bootstrap.
 140                 if (compiler.getGraalRuntime().isBootstrapping()) {
 141                     return ExitVM;
 142                 }
 143             }
 144             return super.lookupAction(values, cause);
 145         }
 146 
 147         @SuppressWarnings("try")
 148         @Override
 149         protected HotSpotCompilationRequestResult performCompilation(DebugContext debug) {
 150             HotSpotResolvedJavaMethod method = getMethod();
 151             int entryBCI = getEntryBCI();
 152             final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
 153             CompilationStatistics stats = CompilationStatistics.create(debug.getOptions(), method, isOSR);
 154 
 155             final CompilationPrinter printer = CompilationPrinter.begin(debug.getOptions(), compilationId, method, entryBCI);
 156 
 157             try (DebugContext.Scope s = debug.scope("Compiling", new DebugDumpScope(getIdString(), true))) {


 158                 result = compiler.compile(method, entryBCI, useProfilingInfo, shouldRetainLocalVariables, compilationId, debug);
 159             } catch (Throwable e) {
 160                 throw debug.handle(e);



 161             }
 162 
 163             if (result != null) {
 164                 try (DebugCloseable b = CodeInstallationTime.start(debug)) {
 165                     installMethod(debug, result);
 166                 }
 167                 // Installation is included in compilation time and memory usage reported by printer
 168                 printer.finish(result);
 169             }
 170             stats.finish(method, installedCode);
 171             if (result != null) {
 172                 return HotSpotCompilationRequestResult.success(result.getBytecodeSize() - method.getCodeSize());
 173             }
 174             return null;
 175         }
 176 
 177     }
 178 
 179     public CompilationTask(HotSpotJVMCIRuntime jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault) {
 180         this(jvmciRuntime, compiler, request, useProfilingInfo, false, installAsDefault);


 274      * Time spent in code installation.
 275      */
 276     public static final TimerKey CodeInstallationTime = DebugContext.timer("CodeInstallation");
 277 
 278     public HotSpotCompilationRequestResult runCompilation(OptionValues initialOptions) {
 279         OptionValues options = filterOptions(initialOptions);
 280         SnippetReflectionProvider snippetReflection = compiler.getGraalRuntime().getHostProviders().getSnippetReflection();
 281         try (DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(snippetReflection))) {
 282             return runCompilation(debug);
 283         }
 284     }
 285 
 286     @SuppressWarnings("try")
 287     public HotSpotCompilationRequestResult runCompilation(DebugContext debug) {
 288         HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
 289         GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
 290         int entryBCI = getEntryBCI();
 291         boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI;
 292         HotSpotResolvedJavaMethod method = getMethod();
 293 



 294         if (installAsDefault || isOSR) {
 295             // If there is already compiled code for this method on our level we simply return.
 296             // JVMCI compiles are always at the highest compile level, even in non-tiered mode so we
 297             // only need to check for that value.
 298             if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) {
 299                 return HotSpotCompilationRequestResult.failure("Already compiled", false);
 300             }
 301             if (HotSpotGraalCompilerFactory.shouldExclude(method)) {
 302                 return HotSpotCompilationRequestResult.failure("GraalCompileOnly excluded", false);
 303             }
 304         }
 305 
 306         HotSpotCompilationWrapper compilation = new HotSpotCompilationWrapper();
 307         try (DebugCloseable a = CompilationTime.start(debug)) {
 308             return compilation.run(debug);
 309         } finally {
 310             try {
 311                 int compiledBytecodes = 0;
 312                 int codeSize = 0;
 313 
 314                 if (compilation.result != null) {
 315                     compiledBytecodes = compilation.result.getBytecodeSize();
 316                     CompiledBytecodes.add(debug, compiledBytecodes);
 317                     if (installedCode != null) {
 318                         codeSize = installedCode.getSize();
 319                         CompiledAndInstalledBytecodes.add(debug, compiledBytecodes);
 320                         InstalledCodeSize.add(debug, codeSize);
 321                     }












 322                 }
 323             } catch (Throwable t) {
 324                 return compilation.handleException(t);
 325             }
 326         }
 327     }
 328 
 329     @SuppressWarnings("try")
 330     private void installMethod(DebugContext debug, final CompilationResult compResult) {
 331         final CodeCacheProvider codeCache = jvmciRuntime.getHostJVMCIBackend().getCodeCache();
 332         HotSpotBackend backend = compiler.getGraalRuntime().getHostBackend();
 333         installedCode = null;
 334         Object[] context = {new DebugDumpScope(getIdString(), true), codeCache, getMethod(), compResult};
 335         try (DebugContext.Scope s = debug.scope("CodeInstall", context)) {
 336             HotSpotCompilationRequest request = getRequest();
 337             installedCode = (HotSpotInstalledCode) backend.createInstalledCode(debug,
 338                             request.getMethod(),
 339                             request,
 340                             compResult,
 341                             null,
< prev index next >