Skip to content

[GR-35847] Allow setting options on per compilation basis #10337

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public static void createOptionsDescriptorsFile(ProcessingEnvironment processing
out.printf(" /*name*/ \"%s\",\n", name);
out.printf(" /*optionType*/ %s.%s,\n", getSimpleName(OPTION_TYPE_CLASS_NAME), optionType);
out.printf(" /*optionValueType*/ %s.class,\n", type);
out.printf(" /*help*/ \"%s\",\n", help);
out.printf(" /*help*/ \"%s\",\n", help.replace("\\", "\\\\").replace("\"", "\\\""));
if (extraHelp.size() != 0) {
out.printf(" /*extraHelp*/ new String[] {\n");
for (String line : extraHelp) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import static jdk.graal.compiler.core.CompilationWrapper.ExceptionAction.ExitVM;
import static jdk.graal.compiler.core.GraalCompilerOptions.CompilationBailoutAsFailure;
import static jdk.graal.compiler.core.GraalCompilerOptions.CompilationFailureAction;
import static jdk.graal.compiler.core.GraalCompilerOptions.PrintCompilation;
import static jdk.graal.compiler.core.phases.HighTier.Options.Inline;
import static jdk.graal.compiler.java.BytecodeParserOptions.InlineDuringParsing;
import static org.graalvm.nativeimage.ImageInfo.inImageRuntimeCode;
Expand All @@ -51,6 +52,7 @@
import jdk.graal.compiler.debug.DebugDumpScope;
import jdk.graal.compiler.debug.DebugHandlersFactory;
import jdk.graal.compiler.debug.GraalError;
import jdk.graal.compiler.debug.MethodFilter;
import jdk.graal.compiler.debug.TTY;
import jdk.graal.compiler.debug.TimerKey;
import jdk.graal.compiler.nodes.StructuredGraph;
Expand Down Expand Up @@ -81,6 +83,17 @@ static class Options {
@Option(help = "Perform a full GC of the libgraal heap after every compile to reduce idle heap and reclaim " +
"references to the HotSpot heap. This flag has no effect in the context of jargraal.", type = OptionType.Debug)//
public static final OptionKey<Boolean> FullGCAfterCompile = new OptionKey<>(false);
@Option(help = "Options which are enabled based on the method being compiled. " +
"The basic syntax is a MethodFilter option specification followed by a list of options to be set for that compilation. " +
"\"MethodFilter:\" is used to distinguish this from normal usage of MethodFilter as option." +
"This can be repeated multiple times with each MethodFilter option separating the groups. " +
"For example:" +
" -D" + HotSpotGraalOptionValues.GRAAL_OPTION_PROPERTY_PREFIX +
".PerMethodOptions=MethodFilter:String.indexOf SpeculativeGuardMovement=false MethodFilter:Integer.* SpeculativeGuardMovement=false" +
" disables SpeculativeGuardMovement for compiles of String.indexOf and all methods in Integer. " +
"If the value starts with a non-letter character, that " +
"character is used as the separator between options instead of a space.")//
public static final OptionKey<String> PerMethodOptions = new OptionKey<>(null);
}

@Override
Expand Down Expand Up @@ -163,7 +176,7 @@ protected HotSpotCompilationRequestResult handleException(Throwable t) {
/*
* Treat random exceptions from the compiler as indicating a problem compiling this
* method. Report the result of toString instead of getMessage to ensure that the
* exception type is included in the output in case there's no detail mesage.
* exception type is included in the output in case there's no detail message.
*/
return HotSpotCompilationRequestResult.failure(t.toString(), false);
}
Expand Down Expand Up @@ -333,25 +346,69 @@ public void setTypeFilter(TypeFilter typeFilter) {
this.profileSaveFilter = typeFilter;
}

public OptionValues filterOptions(OptionValues options) {
public OptionValues filterOptions(OptionValues originalOptions) {
HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
OptionValues newOptions = originalOptions;

// Set any options for this compile.
String perMethodOptions = Options.PerMethodOptions.getValue(originalOptions);
if (perMethodOptions != null) {
EconomicMap<OptionKey<?>, Object> values;
try {
EconomicMap<String, String> optionSettings = null;
for (String option : OptionsParser.splitOptions(perMethodOptions)) {
String prefix = "MethodFilter:";
if (option.startsWith(prefix)) {
MethodFilter filter = MethodFilter.parse(option.substring(prefix.length()));
if (filter.matches(getMethod())) {
// Begin accumulating options
optionSettings = EconomicMap.create();
} else if (optionSettings != null) {
// This is a new MethodFilter: so stop collecting options
break;
}
} else if (optionSettings != null) {
OptionsParser.parseOptionSettingTo(option, optionSettings);
} else {
throw new IllegalArgumentException(Options.PerMethodOptions.getName() + " must start with \"MethodFilter:\" specification");
}
}
if (optionSettings.isEmpty()) {
throw new IllegalArgumentException("No options specified for MethodFilter:");
}
values = EconomicMap.create();
OptionsParser.parseOptions(optionSettings, values, OptionsParser.getOptionsLoader());
} catch (Exception e) {
values = null;
TTY.println(e.toString());
TTY.println("Errors encountered during " + Options.PerMethodOptions.getName() + " parsing. Exiting...");
HotSpotGraalServices.exit(-1, jvmciRuntime);
}

if (values != null) {
newOptions = new OptionValues(newOptions, values);
if (PrintCompilation.getValue(newOptions)) {
TTY.println("Compiling " + getMethod() + " with extra options: " + new OptionValues(values));
}
}
}
/*
* Disable inlining if HotSpot has it disabled unless it's been explicitly set in Graal.
*/
HotSpotGraalRuntimeProvider graalRuntime = compiler.getGraalRuntime();
GraalHotSpotVMConfig config = graalRuntime.getVMConfig();
OptionValues newOptions = options;
if (!config.inline) {
EconomicMap<OptionKey<?>, Object> m = OptionValues.newOptionMap();
if (Inline.getValue(options) && !Inline.hasBeenSet(options)) {
if (Inline.getValue(newOptions) && !Inline.hasBeenSet(newOptions)) {
m.put(Inline, false);
}
if (InlineDuringParsing.getValue(options) && !InlineDuringParsing.hasBeenSet(options)) {
if (InlineDuringParsing.getValue(newOptions) && !InlineDuringParsing.hasBeenSet(newOptions)) {
m.put(InlineDuringParsing, false);
}
if (!m.isEmpty()) {
newOptions = new OptionValues(options, m);
newOptions = new OptionValues(newOptions, m);
}
}

return newOptions;
}

Expand Down