|
28 | 28 | import static jdk.graal.compiler.core.CompilationWrapper.ExceptionAction.ExitVM; |
29 | 29 | import static jdk.graal.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure; |
30 | 30 | import static jdk.graal.compiler.core.GraalCompilerOptions.CompilationFailureAction; |
| 31 | +import static jdk.graal.compiler.core.GraalCompilerOptions.PrintCompilation; |
31 | 32 | import static jdk.graal.compiler.core.phases.HighTier.Options.Inline; |
32 | 33 | import static jdk.graal.compiler.java.BytecodeParserOptions.InlineDuringParsing; |
33 | 34 | import static org.graalvm.nativeimage.ImageInfo.inImageRuntimeCode; |
|
51 | 52 | import jdk.graal.compiler.debug.DebugDumpScope; |
52 | 53 | import jdk.graal.compiler.debug.DebugHandlersFactory; |
53 | 54 | import jdk.graal.compiler.debug.GraalError; |
| 55 | +import jdk.graal.compiler.debug.MethodFilter; |
54 | 56 | import jdk.graal.compiler.debug.TTY; |
55 | 57 | import jdk.graal.compiler.debug.TimerKey; |
56 | 58 | import jdk.graal.compiler.nodes.StructuredGraph; |
@@ -81,6 +83,17 @@ static class Options { |
81 | 83 | @Option(help = "Perform a full GC of the libgraal heap after every compile to reduce idle heap and reclaim " + |
82 | 84 | "references to the HotSpot heap. This flag has no effect in the context of jargraal.", type = OptionType.Debug)// |
83 | 85 | public static final OptionKey<Boolean> FullGCAfterCompile = new OptionKey<>(false); |
| 86 | + @Option(help = "Options which are enabled based on the method being compiled. " + |
| 87 | + "The basic syntax is a MethodFilter option specification followed by a list of options to be set for that compilation. " + |
| 88 | + "\"MethodFilter:\" is used to distinguish this from normal usage of MethodFilter as option." + |
| 89 | + "This can be repeated multiple times with each MethodFilter option separating the groups. " + |
| 90 | + "For example:" + |
| 91 | + " -D" + HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX + |
| 92 | + ".PerMethodOptions=MethodFilter:String.indexOf SpeculativeGuardMovement=false MethodFilter:Integer.* SpeculativeGuardMovement=false" + |
| 93 | + " disables SpeculativeGuardMovement for compiles of String.indexOf and all methods in Integer. " + |
| 94 | + "If the value starts with a non-letter character, that " + |
| 95 | + "character is used as the separator between options instead of a space.")// |
| 96 | + public static final OptionKey<String> PerMethodOptions = new OptionKey<>(null); |
84 | 97 | } |
85 | 98 |
|
86 | 99 | @Override |
@@ -163,7 +176,7 @@ protected HotSpotCompilationRequestResult handleException(Throwable t) { |
163 | 176 | /* |
164 | 177 | * Treat random exceptions from the compiler as indicating a problem compiling this |
165 | 178 | * method. Report the result of toString instead of getMessage to ensure that the |
166 | | - * exception type is included in the output in case there's no detail mesage. |
| 179 | + * exception type is included in the output in case there's no detail message. |
167 | 180 | */ |
168 | 181 | return HotSpotCompilationRequestResult.failure(t.toString(), false); |
169 | 182 | } |
@@ -333,25 +346,69 @@ public void setTypeFilter(TypeFilter typeFilter) { |
333 | 346 | this.profileSaveFilter = typeFilter; |
334 | 347 | } |
335 | 348 |
|
336 | | - public OptionValues filterOptions(OptionValues options) { |
| 349 | + public OptionValues filterOptions(OptionValues originalOptions) { |
| 350 | + HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime(); |
| 351 | + GraalHotSpotVMConfig config = graalRuntime.getVMConfig(); |
| 352 | + OptionValues newOptions = originalOptions; |
| 353 | + |
| 354 | + // Set any options for this compile. |
| 355 | + String perMethodOptions = Options.PerMethodOptions.getValue(originalOptions); |
| 356 | + if (perMethodOptions != null) { |
| 357 | + EconomicMap<OptionKey<?>, Object> values; |
| 358 | + try { |
| 359 | + EconomicMap<String, String> optionSettings = null; |
| 360 | + for (String option : OptionsParser.splitOptions(perMethodOptions)) { |
| 361 | + String prefix = "MethodFilter:"; |
| 362 | + if (option.startsWith(prefix)) { |
| 363 | + MethodFilter filter = MethodFilter.parse(option.substring(prefix.length())); |
| 364 | + if (filter.matches(getMethod())) { |
| 365 | + // Begin accumulating options |
| 366 | + optionSettings = EconomicMap.create(); |
| 367 | + } else if (optionSettings != null) { |
| 368 | + // This is a new MethodFilter: so stop collecting options |
| 369 | + break; |
| 370 | + } |
| 371 | + } else if (optionSettings != null) { |
| 372 | + OptionsParser.parseOptionSettingTo(option, optionSettings); |
| 373 | + } else { |
| 374 | + throw new IllegalArgumentException(Options.PerMethodOptions.getName() + " must start with \"MethodFilter:\" specification"); |
| 375 | + } |
| 376 | + } |
| 377 | + if (optionSettings.isEmpty()) { |
| 378 | + throw new IllegalArgumentException("No options specified for MethodFilter:"); |
| 379 | + } |
| 380 | + values = EconomicMap.create(); |
| 381 | + OptionsParser.parseOptions(optionSettings, values, OptionsParser.getOptionsLoader()); |
| 382 | + } catch (Exception e) { |
| 383 | + values = null; |
| 384 | + TTY.println(e.toString()); |
| 385 | + TTY.println("Errors encountered during " + Options.PerMethodOptions.getName() + " parsing. Exiting..."); |
| 386 | + HotSpotGraalServices.exit(-1, jvmciRuntime); |
| 387 | + } |
| 388 | + |
| 389 | + if (values != null) { |
| 390 | + newOptions = new OptionValues(newOptions, values); |
| 391 | + if (PrintCompilation.getValue(newOptions)) { |
| 392 | + TTY.println("Compiling " + getMethod() + " with extra options: " + new OptionValues(values)); |
| 393 | + } |
| 394 | + } |
| 395 | + } |
337 | 396 | /* |
338 | 397 | * Disable inlining if HotSpot has it disabled unless it's been explicitly set in Graal. |
339 | 398 | */ |
340 | | - HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime(); |
341 | | - GraalHotSpotVMConfig config = graalRuntime.getVMConfig(); |
342 | | - OptionValues newOptions = options; |
343 | 399 | if (!config.inline) { |
344 | 400 | EconomicMap<OptionKey<?>, Object> m = OptionValues.newOptionMap(); |
345 | | - if (Inline.getValue(options) && !Inline.hasBeenSet(options)) { |
| 401 | + if (Inline.getValue(newOptions) && !Inline.hasBeenSet(newOptions)) { |
346 | 402 | m.put(Inline, false); |
347 | 403 | } |
348 | | - if (InlineDuringParsing.getValue(options) && !InlineDuringParsing.hasBeenSet(options)) { |
| 404 | + if (InlineDuringParsing.getValue(newOptions) && !InlineDuringParsing.hasBeenSet(newOptions)) { |
349 | 405 | m.put(InlineDuringParsing, false); |
350 | 406 | } |
351 | 407 | if (!m.isEmpty()) { |
352 | | - newOptions = new OptionValues(options, m); |
| 408 | + newOptions = new OptionValues(newOptions, m); |
353 | 409 | } |
354 | 410 | } |
| 411 | + |
355 | 412 | return newOptions; |
356 | 413 | } |
357 | 414 |
|
|
0 commit comments