This topic examines Compiler Control options and steps for writing directives from those options.
本主题研究编译器控制选项和编写来自那些选项的指令的步骤。
Topics:
- Compiler Control Options
- Writing a Directive File
- Writing a Compiler Directive
- Writing a Method Pattern in a Compiler Directive
- Writing an Inline Directive Option
- Preventing Duplication with the Enable Option
Compiler Control Options
Options are instructions for compilation. Options provide method-context precision. Available options vary by compiler and require specific types of values.
选项是对编译的指令。选项提供了方法上下文精确度。可用选项根据编译器而变,并且要求特定的值类型。
Table 2-1 Common Options 常用选项
Option | Description | Value Type | Default Value |
Enable | Hides a directive and renders it unmatchable if it is set to false. This option is useful for preventing option duplication. See Preventing Duplication with the Enable Option. 如果此选项设置为false,则编译器控制会隐藏一个指令,并且渲染它为不匹配的。此选项可用于阻止选项重复。 | bool | true |
Exclude | Excludes methods from compilation. 编译时排除方法。 | bool | false |
BreakAtExecute | Sets a breakpoint to stop execution at the beginning of the specified methods when debugging the JVM. Debug JVM时,此选项用于在指定方法开始的时候设置一个断点来停止执行。 | bool | false |
BreakAtCompile | Sets a breakpoint to stop compilation at the beginning of the specified methods when debugging the JVM. Debug JVM时,此选项用于在指定方法开始的时候设置一个断点来停止编译。 | bool | false |
Log | Places only the specified methods in a log. You must first set the command-line option -XX:+LogCompilation. The default value false places all compiled methods in a log. 只将指定方法放入日志中。首先,你必须设置命令行选项: -XX:+LogCompilation。默认值为 false,将所有编译的方法都放入日志中。 | bool | false |
PrintAssembly | Prints assembly code for bytecoded and native methods by using the external disassembler.so library. 使用外部 disassembler.so 库为字节码和本地方法打印汇编代码。 | bool | false |
PrintInlining | Prints which methods are inlined, and where. 打印哪个方法是内联的,并且指出位置。 | bool | false |
PrintNMethods | Prints nmethods as they are generated. 在 nmethods 生成后打印它们。 | bool | false |
BackgroundCompilation | Compiles methods as a background task. Methods run in interpreter mode until the background compilation finishes. The value false compiles methods as a foreground task. 编译方法作为后台任务执行。方法使用解释器模式运行,直到后台编译结束。默认值为 true,编译方法作为前台任务执行。 | bool | true |
ReplayInline | Enables the same CIReplay functionality as the corresponding global option, but on a per-method basis. 启用与对应的全局选项相同的 CIReplay 功能,但是以每个方法为基础。 | bool | false |
DumpReplay | Enables the same CIReplay functionality as the corresponding global option, but on a per-method basis. 启用与对应的全局选项相同的 CIReplay 功能,但是以每个方法为基础。 | bool | false |
DumpInline | Enables the same CIReplay functionality as the corresponding global option, but on a per-method basis. 启用与对应的全局选项相同的 CIReplay 功能,但是以每个方法为基础。 | bool | false |
CompilerDirectivesIgnoreCompileCommands | Disregards all CompileCommands. 忽略所有的编译命令。 | bool | false |
DisableIntrinsic | Disables the use of intrinsics based on method-matching criteria. 基于方法匹配准则的关闭内联方法使用。 | ccstr | No default value. |
inline | Forces or prevents inlining of a method based on method-matching criteria. See Writing an Inline Directive Option. 强制或者阻止基于方法匹配准则的方法内联。 | ccstr[] | No default value. |
Table 2-2 C2 Exclusive Options C2独有选项
Option | Description | Value Type | Default Value |
BlockLayoutByFrequency | Moves infrequent execution branches from the hot path. | bool | true |
PrintOptoAssembly | Prints generated assembly code after compilation by using the external disassembler.so library. This requires a debugging build of the JVM. | bool | false |
PrintIntrinsics | Prints which intrinsic methods are used, and where. | bool | false |
TraceOptoPipelining | Traces pipelining information, similar to the corresponding global option, but on a per-method basis. This is intended for slow and fast debugging builds. | bool | false |
TraceOptoOutput | Traces pipelining information, similar to the corresponding global option, but on a per-method basis. This is intended for slow and fast debugging builds. | bool | false |
TraceSpilling | Traces variable spilling. | bool | false |
Vectorize | Performs calculations in parallel, across vector registers. | bool | false |
VectorizeDebug | Performs calculations in parallel, across vector registers. This requires a debugging build of the JVM. | intx | 0 |
CloneMapDebug | Enables you to examine the CloneMap generated from vectorization. This requires a debugging build of the JVM. | bool | false |
IGVPrintLevel | Specifies the points where the compiler graph is printed in Oracle’s Hotspot Ideal Graphic Visualizer (IGV). A higher value means higher granularity. | intx | 0 |
MaxNodeLimit | Sets the maximum number of nodes to use during a single method’s compilation. | intx | 80000 |
A ccstr value type is a method pattern. See Writing a Method Pattern in a Compiler Directive.
The default directive supplies default values for compiler options. See What Is the Default Directive?
Writing a Directive File
Individual compiler directives are written in a directives file. Only directive files, not individual directives, can be added to the stack of active directives.
- Create a file with a .json extension. Directive files are written using a subset of JSON syntax with minor additions and deviations.
- Add the following syntax as a template you can work from:
[ //Array of Directives
{ //Directive Block
//Directive 1
},
{ //Directive Block
//Directive 2
},
]
The components of this template are:
Array of Directives- A directives file stores an array of directive blocks, denoted with a pair of brackets ([]).
- The brackets are optional if the file contains only a single directive block.
Directive Block - A block is denoted with a pair of braces ({}).
- A block contains one individual directive.
- A directives file can contain any number of directive blocks.
- Blocks are separated with a comma (,).
- A comma is optional following the final block in the array.
Directive - Each directive must be within a directive block.
- A directives file can contain multiple directives when it contains multiple directive blocks.
Comments - Single-line comments are preceded with two slashes (//).
- Multiline comments are not allowed.
- Add or remove directive blocks from the template to match the number of directives you want in the directives file.
- In each directive block, write one compiler directive. See Writing a Compiler Directive.
- Reorder the directive blocks if necessary. The ordering of directives in a file is significant. Directives written closer to the beginning of the array receive higher priority. For more information, see How Directives Are Ordered in the Directives Stack? and How Directives are Applied to Code?
The following example shows a completed directives file that contains two compiler directives:
[ //Array of directives
{ //Directive Block
//Directive 1
match: ["java*.*", "oracle*.*"],
c1: {
Enable: true,
Exclude: true,
BreakAtExecute: true,
},
c2: {
Enable: false,
MaxNodeLimit: 1000,
},
BreakAtCompile: true,
DumpReplay: true,
},
{ //Directive Block
//Directive 2
match: ["*Concurrent.*"],
c2: {
Exclude:true,
},
},
]
Writing a Compiler Directive
You must write a compiler directive within a directives file. You can repeat the following steps for each individual compiler directive that you want to write in a directives file.
An individual compiler directive is written within a directive block in a directives file. See Writing a Directive File.
- Insert the following block of code, as a template you can work from, to write an individual compiler directive. This block of code is a directive block.
{
match: [],
c1: {
//c1 directive options
},
c2: {
//c2 directive options
},
//Directive options applicable to all compilers
}, - Provide the match attribute with an array of method patterns. See Writing a Method Pattern in a Compiler Directive.
For example:
match: ["java*.*", "oracle*.*"], - Provide the c1 attribute with a block of comma-separated directive options. Ensure that these options are valid for the c1 compiler.
For example:
c1: {
Enable: true,
Exclude: true,
BreakAtExecute: true,
}, - Provide the c2 attribute with a block of comma-separated directive options. This block can contain a mix of common and c2-exclusive compiler options.
For example:
c2: {
Enable: false,
MaxNodeLimit: 1000,
}, - Provide, at the end of the directive, options you want applicable to all compilers. These options are considered written within the scope of the common block. Options are comma-separated.
For example:
BreakAtCompile: true,
DumpReplay: true, - Clean up the file by completing the following steps.
- Check for the duplication of directive options. If a conflict occurs, then the last occurrence of an option takes priority. Conflicts typically occur between the common block and the c1 or c2 blocks, not between the c1 and c2 blocks.
- Avoid writing c2-exclusive directive options in the common block. Although the common block can accept a mix of common and c2-exclusive options, it’s pointless to structure a directive this way because c2-exclusive options in the common block have no effect on the c1 compiler. Write c2-exclusive options within the c2 block instead.
- If the c1 or c2 attribute has no corresponding directive options, then omit the attribute-value syntax for that compiler.
The following example shows the resulting directive, based on earlier examples, is:
{
match: ["java*.*", "oracle*.*"],
c1: {
Enable: true,
Exclude: true,
BreakAtExecute: true,
},
c2: {
Enable: false,
MaxNodeLimit: 1000,
},
BreakAtCompile: true,
DumpReplay: true,
},
The JSON format of directive files allows the following deviations in syntax:
- Extra trailing commas are optional in arrays and objects.
- Attributes are strings and are optionally placed within quotation marks.
- If an array contains only one element, then brackets are optional.
Therefore, the following example shows a valid compiler directive:
{
"match": "*Concurrent.*",
c2: {
"Exclude": true,
}
},
Writing a Method Pattern in a Compiler Directive
A ccstr is a method pattern that you can write precisely or you can generalize with wildcard characters. You can specify what best-matching Java code should have accompanying directive options applied, or what Java code should be inlined.
To write a method pattern:
- Use the following syntax to write your method pattern: package/class.method(parameter_list). To generalize a method pattern with wildcard characters, see Step 2.
The following example shows a method pattern that uses this syntax:
java/lang/String.indexOf()
Other formatting styles are available. This ensures backward compatibility with earlier ways of method matching such as CompileCommand. Valid formatting alternatives for the previous example include:- java/lang/String.indexOf()
- java/lang/String,indexOf()
- java/lang/String indexOf()
- java.lang.String::indexOf()
The last formatting style matches the HotSpot output.
- Insert a wildcard character (*) where you want to generalize part of the method pattern.
The following examples are valid generalizations of the method pattern example in Step 1:- java/lang/String.indexOf*
- *lang/String.indexOf*
- *va/lang*.*dex*
- java/lang/String.*
- *.*
Increased generalization leads to decreased precision. More Java code becomes a potential match with the method pattern. Therefore, it’s important to use the wildcard character (*) judiciously.
- Modify the signature portion of the method pattern, according to the Java Specifications. A signature match must be exact, otherwise the signature defaults to a wildcard character (*). Omitted signatures also default to a wildcard character. Signatures cannot contain the wildcard character.
- Optional: If you write a method pattern to accompany the inline directive option, then you must prefix the method pattern with additional characters. See Writing an Inline Directive Option.
Writing an Inline Directive Option
The attribute for an inline directive option requires an array of method patterns with special commands prefixed. This indicates which method patterns should or shouldn’t inline.
- Write inline: in the common block, c1 block , or c2 block of a directive.
- Add an array of carefully ordered method patterns. The prefixed command on the first matching method pattern is executed. The remaining method patterns in the array are ignored.
- Prefix a + to force inlining of any matching Java code.
- Prefix a - to prevent inlining of any matching Java code.
- Optional: If you need inlining behavior applied to multiple method patterns, then repeat Steps 1 to 4 to write multiple inlinestatements. Don’t write a single array that contains multiple method patterns.
The following examples show the inline directive options:
- inline: ["+java/lang*.*", "-sun*.*"]
- inline: "+java/lang*.*"
Preventing Duplication with the Enable Option
You can use the Enable option to hide aspects of directives and prevent duplication between directives.
In the following example, the c1attribute of the compiler directives are identical.:
[
{
match: ["java*.*"],
c1: {
BreakAtExecute: true,
BreakAtCompile: true,
DumpReplay: true,
DumpInline: true,
},
c2: {
MaxNodeLimit: 1000,
},
},
{
match: ["oracle*.*"],
c1: {
BreakAtExecute: true,
BreakAtCompile: true,
DumpReplay: true,
DumpInline: true,
},
c2: {
MaxNodeLimit: 2000,
},
},
]
The following example shows how the undesirable code duplication is resolved with the Enable option. Enable hides the block directives and renders them unmatchable.
[
{
match: ["java*.*"],
c1: {
Enable: false,
},
c2: {
MaxNodeLimit: 1000,
},
},
{
match: ["oracle*.*"],
c1: {
Enable: false,
},
c2: {
MaxNodeLimit: 2000,
},
},
{
match: ["java*.*", "oracle*.*"],
c1: {
BreakAtExecute: true,
BreakAtCompile: true,
DumpReplay: true,
DumpInline: true,
},
c2: {
//Unreachable code
},
},
]
Typically, the first matching directive is applied to a method’s compilation. The Enable option provides an exception to this rule. A method that would typically be compiled by c1 in the first or second directive is now compiled with the c1 block of the third directive. The c2 block of the third directive is unreachable because the c2 blocks in the first and second directive take priority.