Skip to content

Commit d594773

Browse files
committed
[GR-63557] Inline multi-line help text for options.
PullRequest: graal/20413
2 parents fe0fdb7 + dfb0c79 commit d594773

File tree

27 files changed

+353
-345
lines changed

27 files changed

+353
-345
lines changed

compiler/src/jdk.graal.compiler.libgraal/src/jdk/graal/compiler/libgraal/LibGraalFeature.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ void afterAnalysis(AfterAnalysisAccess access) {
232232
Map<String, String> modules = libgraalLoader.getClassModuleMap();
233233
for (OptionKey<?> option : options) {
234234
OptionDescriptor descriptor = option.getDescriptor();
235-
if (descriptor != null) {
235+
if (descriptor != null && descriptor.getContainer().optionsAreServiceLoadable()) {
236236
GraalError.guarantee(access.isReachable(option.getClass()), "%s", option.getClass());
237237
GraalError.guarantee(access.isReachable(descriptor.getClass()), "%s", descriptor.getClass());
238238

compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/options/processor/OptionProcessor.java

+52-43
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
*/
2525
package jdk.graal.compiler.options.processor;
2626

27-
import java.io.BufferedReader;
2827
import java.io.IOException;
29-
import java.io.InputStreamReader;
28+
import java.io.InputStream;
3029
import java.io.PrintWriter;
30+
import java.nio.charset.StandardCharsets;
3131
import java.util.ArrayList;
3232
import java.util.Collections;
3333
import java.util.HashMap;
@@ -185,72 +185,81 @@ private void processElement(Element element, OptionsDeclarer optionsDeclarer) {
185185
processingEnv.getMessager().printMessage(Kind.ERROR, "Option field cannot be declared in the unnamed package", element);
186186
return;
187187
}
188-
List<String> helpValue = getAnnotationValueList(annotation, "help", String.class);
189-
String help = "";
190-
List<String> extraHelp = new ArrayList<>();
191-
192-
if (helpValue.size() == 1) {
193-
help = helpValue.getFirst();
194-
if (help.startsWith("file:")) {
195-
String path = help.substring("file:".length());
196-
Filer filer = processingEnv.getFiler();
188+
189+
String help = getAnnotationValue(annotation, "help", String.class);
190+
List<String> helpLines;
191+
if (help.startsWith("file:")) {
192+
String path = help.substring("file:".length());
193+
Filer filer = processingEnv.getFiler();
194+
try {
195+
FileObject file;
197196
try {
198-
FileObject file;
199-
try {
200-
file = filer.getResource(StandardLocation.SOURCE_PATH, enclosingPackage.getQualifiedName(), path);
201-
} catch (IllegalArgumentException | IOException e) {
202-
// Handle the case when a compiler doesn't support the SOURCE_PATH location
203-
file = filer.getResource(StandardLocation.CLASS_OUTPUT, enclosingPackage.getQualifiedName(), path);
204-
}
205-
try (BufferedReader br = new BufferedReader(new InputStreamReader(file.openInputStream()))) {
206-
help = br.readLine();
207-
if (help == null) {
208-
help = "";
209-
}
210-
String line = br.readLine();
211-
while (line != null) {
212-
extraHelp.add(line);
213-
line = br.readLine();
214-
}
215-
}
216-
} catch (IOException e) {
217-
String msg = String.format("Error reading %s containing the help text for option field: %s", path, e);
218-
processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
219-
return;
197+
file = filer.getResource(StandardLocation.SOURCE_PATH, enclosingPackage.getQualifiedName(), path);
198+
} catch (IllegalArgumentException | IOException e) {
199+
// Handle the case when a compiler doesn't support the SOURCE_PATH location
200+
file = filer.getResource(StandardLocation.CLASS_OUTPUT, enclosingPackage.getQualifiedName(), path);
201+
}
202+
try (InputStream in = file.openInputStream()) {
203+
help = new String(in.readAllBytes(), StandardCharsets.UTF_8);
204+
helpLines = List.of(help.split(System.lineSeparator()));
220205
}
206+
} catch (IOException e) {
207+
String msg = String.format("Error reading %s containing the help text for option field: %s", path, e);
208+
processingEnv.getMessager().printMessage(Kind.ERROR, msg, element);
209+
return;
221210
}
222-
} else if (helpValue.size() > 1) {
223-
help = helpValue.getFirst();
224-
extraHelp = helpValue.subList(1, helpValue.size());
211+
} else {
212+
helpLines = List.of(help.split("\\n"));
225213
}
226-
if (!help.isEmpty()) {
227-
char firstChar = help.charAt(0);
214+
215+
String briefHelp = helpLines.getFirst();
216+
List<String> extraHelp;
217+
if (briefHelp.isEmpty()) {
218+
if (helpLines.size() > 1) {
219+
processingEnv.getMessager().printMessage(Kind.ERROR, "First line of multi-line help text cannot be empty", element);
220+
return;
221+
}
222+
extraHelp = List.of();
223+
} else {
224+
if (helpLines.size() > 1) {
225+
if (briefHelp.charAt(briefHelp.length() - 1) != '.' && !helpLines.get(1).isBlank()) {
226+
processingEnv.getMessager().printMessage(Kind.ERROR,
227+
"First line of multi-line help text must end with a period or be followed by a blank line", element);
228+
return;
229+
}
230+
}
231+
char firstChar = briefHelp.charAt(0);
228232
if (!Character.isUpperCase(firstChar)) {
229233
processingEnv.getMessager().printMessage(Kind.ERROR, "Option help text must start with an upper case letter", element);
230234
return;
231235
}
236+
extraHelp = helpLines.subList(1, helpLines.size());
232237
}
233238

234239
String stability = getAnnotationValue(annotation, "stability", VariableElement.class).getSimpleName().toString();
235240
if (stability.equals("STABLE")) {
236-
if (help.isEmpty()) {
241+
if (briefHelp.isEmpty()) {
237242
processingEnv.getMessager().printMessage(Kind.ERROR, "A stable option must have non-empty help text", element);
238243
return;
239244
}
240245
}
241246

242247
String optionTypeName = getAnnotationValue(annotation, "type", VariableElement.class).getSimpleName().toString();
243248
if (!optionTypeName.equals("Debug")) {
244-
if (help.isEmpty()) {
249+
if (briefHelp.isEmpty()) {
245250
processingEnv.getMessager().printMessage(Kind.ERROR, "Non debug options must always have a option help text " + optionName);
246251
}
247252
}
248253
boolean deprecated = getAnnotationValue(annotation, "deprecated", Boolean.class);
249254
String deprecationMessage = getAnnotationValue(annotation, "deprecationMessage", String.class);
250-
OptionInfo info = new OptionInfo(optionName, optionTypeName, help, extraHelp, optionType, declaringClass, fieldName, stability, deprecated, deprecationMessage);
255+
OptionInfo info = new OptionInfo(optionName, optionTypeName, briefHelp, extraHelp, optionType, declaringClass, fieldName, stability, deprecated, deprecationMessage);
251256
optionsDeclarer.options.add(info);
252257
}
253258

259+
private static String literal(String help) {
260+
return "\"" + help.replace("\\", "\\\\").replace("\"", "\\\"") + "\"";
261+
}
262+
254263
static void createOptionsDescriptorsFile(ProcessingEnvironment processingEnv, OptionsDeclarer optionsDeclarer) {
255264
Element[] originatingElements = optionsDeclarer.originatingElements.toArray(new Element[0]);
256265
String optionsDescriptorsClassName = optionsDeclarer.getOptionDescriptorsClassName();
@@ -310,11 +319,11 @@ static void createOptionsDescriptorsFile(ProcessingEnvironment processingEnv, Op
310319
out.printf(" /*name*/ \"%s\",\n", name);
311320
out.printf(" /*optionType*/ %s.%s,\n", getSimpleName(OPTION_TYPE_CLASS_NAME), optionType);
312321
out.printf(" /*optionValueType*/ %s.class,\n", type);
313-
out.printf(" /*help*/ \"%s\",\n", help.replace("\\", "\\\\").replace("\"", "\\\""));
322+
out.printf(" /*help*/ %s,\n", literal(help));
314323
if (!extraHelp.isEmpty()) {
315324
out.printf(" /*extraHelp*/ new String[] {\n");
316325
for (String line : extraHelp) {
317-
out.printf(" \"%s\",\n", line.replace("\\", "\\\\").replace("\"", "\\\""));
326+
out.printf(" %s,\n", literal(line));
318327
}
319328
out.printf(" },\n");
320329
}

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/GraalCompilerOptions.java

+21-6
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,30 @@ public class GraalCompilerOptions {
3939
// @formatter:off
4040
@Option(help = "Print an informational line to the console for each completed compilation.", type = OptionType.Debug, stability = OptionStability.STABLE)
4141
public static final OptionKey<Boolean> PrintCompilation = new OptionKey<>(false);
42-
@Option(help = "Pattern for method(s) that will trigger an exception when compiled. " +
43-
"This option exists to test handling compilation crashes gracefully. " +
44-
"See the MethodFilter option for the pattern syntax. A ':Bailout' " +
45-
"suffix will raise a bailout exception and a ':PermanentBailout' " +
46-
"suffix will raise a permanent bailout exception.", type = OptionType.Debug)
42+
@Option(help = """
43+
Pattern for method(s) that will trigger an exception when compiled.
44+
This option exists to test handling compilation crashes gracefully.
45+
See the MethodFilter option for the pattern syntax. A ':Bailout'
46+
suffix will raise a bailout exception and a ':PermanentBailout'
47+
suffix will raise a permanent bailout exception.""", type = OptionType.Debug)
4748
public static final OptionKey<String> CrashAt = new OptionKey<>(null);
4849
@Option(help = "Treats compilation bailouts as compilation failures.", type = OptionType.User, stability = OptionStability.STABLE)
4950
public static final OptionKey<Boolean> CompilationBailoutAsFailure = new OptionKey<>(false);
50-
@Option(help = "file:doc-files/CompilationFailureActionHelp.txt", type = OptionType.User, stability = OptionStability.STABLE)
51+
@Option(help = """
52+
Specifies the action to take when compilation fails.
53+
54+
The accepted values are:
55+
Silent - Prints nothing to the console.
56+
Print - Prints the stack trace to the console.
57+
Diagnose* - Retries the compilation with extra diagnostics.
58+
ExitVM - Same as Diagnose except that the VM process exits after retrying.
59+
60+
* If the value is "Diagnose", compilation is retried with extra diagnostics enabled including dumping.
61+
Options specific to retry compilations can be modified using the DiagnoseOptions meta-option.
62+
For example, to enable full debug dumping and logging during all retry compilations, use "-Djdk.graal.DiagnoseOptions=Dump=:5 Log=:5".
63+
If the option value starts with a non-word character, that character is used as the separator between options instead of a space.
64+
For example: "-Djdk.graal.DiagnoseOptions=@Log=Inlining@LogFile=/path/with space".""",
65+
type = OptionType.User, stability = OptionStability.STABLE)
5166
public static final EnumOptionKey<ExceptionAction> CompilationFailureAction = new EnumOptionKey<>(ExceptionAction.Silent);
5267
@Option(help = "Specifies the maximum number of compilation failures to handle with the action specified by " +
5368
"CompilationFailureAction before changing to a less verbose action. " +

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/GraalOptions.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,15 @@ public final class GraalOptions {
291291
@Option(help = "Use a cache for snippet graphs.", type = OptionType.Debug)
292292
public static final OptionKey<Boolean> UseSnippetGraphCache = new OptionKey<>(true);
293293

294-
@Option(help = "file:doc-files/TraceInliningHelp.txt", type = OptionType.Debug, stability = OptionStability.STABLE)
294+
@Option(help = """
295+
Enable tracing of inlining decisions.
296+
Output format:
297+
compilation of 'Signature of the compilation root method':
298+
at 'Signature of the root method' ['Bytecode index']: <'Phase'> 'Child method signature': 'Decision made about this callsite'
299+
at 'Signature of the child method' ['Bytecode index']:
300+
|--<'Phase 1'> 'Grandchild method signature': 'First decision made about this callsite'
301+
\\--<'Phase 2'> 'Grandchild method signature': 'Second decision made about this callsite'
302+
at 'Signature of the child method' ['Bytecode index']: <'Phase'> 'Another grandchild method signature': 'The only decision made about this callsite.'""", type = OptionType.Debug, stability = OptionStability.STABLE)
295303
public static final OptionKey<Boolean> TraceInlining = new OptionKey<>(false);
296304

297305
@Option(help = "Enable inlining decision tracing in stubs and snippets.", type = OptionType.Debug)

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/SpectrePHTMitigations.java

+14-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,20 @@ protected void onValueUpdate(EconomicMap<OptionKey<?>, Object> values, Boolean o
6464
}
6565
};
6666

67-
@Option(help = "file:doc-files/MitigateSpeculativeExecutionAttacksHelp.txt", type = OptionType.Expert)
67+
@Option(help = """
68+
Selects a strategy to mitigate speculative bounds check bypass (also known as Spectre-PHT or Spectre V1).
69+
The accepted values are:
70+
None - No mitigations are used in JIT compiled code.
71+
AllTargets - Speculative execution on all branch targets is
72+
stopped using speculative execution barrier instructions.
73+
This option is equivalent to setting SpeculativeExecutionBarriers to true.
74+
GuardTargets - Branch targets relevant to Java memory safety are instrumented with barrier instructions.
75+
This option has a lower performance impact than AllTargets.
76+
NonDeoptGuardTargets - Same as GuardTargets, except that branches which deoptimize are not protected because they cannot be
77+
executed repeatedly and are thus less likely to be successfully exploited in an attack.
78+
79+
80+
Note that all modes except "None" also instrument branch target blocks containing UNSAFE memory accesses with barrier instructions.""", type = OptionType.Expert)
6881
public static final EnumOptionKey<SpectrePHTMitigations> SpectrePHTBarriers = new EnumOptionKey<>(None) {
6982
private boolean isSpeculativeExecutionBarriersEnabled(UnmodifiableEconomicMap<OptionKey<?>, Object> values) {
7083
Object value = values.get(SpeculativeExecutionBarriers);

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/doc-files/MitigateSpeculativeExecutionAttacksHelp.txt

-13
This file was deleted.

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/common/doc-files/TraceInliningHelp.txt

-8
This file was deleted.

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/core/doc-files/CompilationFailureActionHelp.txt

-13
This file was deleted.

0 commit comments

Comments
 (0)