Understanding Directives
The following topics examine how directives behave and interact.
What Is the Default Directive?
The default directive is a compiler directive that contains default values for all possible directive options. It is the bottom-most directives in the stack and matches every method submitted for compilation.
When you design a new compiler directive, you specify how the new directive differs from the default directive. The default directive becomes a template to guide your design decisions.
Directive Option Values in the Default Directive
Directive: (default)
matching: *.*
c1 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false BackgroundCompilation:true ReplayInline:false DumpReplay:false DumpInline:false CompilerDirectivesIgnoreCompileCommands:false DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
c2 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false BackgroundCompilation:true ReplayInline:false DumpReplay:false DumpInline:false CompilerDirectivesIgnoreCompileCommands:false DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
Note:
Certain options are applicable exclusively to thec2
compiler. For a complete list, see Table 2-2.
Directive Option Values in New Directives
In a new directives, you must specify how the directive differs from the default directive. If you don’t specify a directive option, then that option retains the value from the default directive.
[
{
match: ["*Concurrent.*"],
c2: {
MaxNodeLimit: 1000,
},
Exclude:true,
},
]
When you add a new directive to the directives stack, the default directive becomes the bottom-most directive in the stack. See How Directives Are Ordered in the Directives Stack? for a description of this process. For this example, when you print the directives stack, it shows how the directive options specified in the new directive differ from the values in the default directive:Directive:
matching: *Concurrent.*
c1 directives:
inline: -
Enable:true Exclude:true BreakAtExecute:false BreakAtCompile:false Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false BackgroundCompilation:true ReplayInline:false DumpReplay:false DumpInline:false CompilerDirectivesIgnoreCompileCommands:false DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
c2 directives:
inline: -
Enable:true Exclude:true BreakAtExecute:false BreakAtCompile:false Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false BackgroundCompilation:true ReplayInline:false DumpReplay:false DumpInline:false CompilerDirectivesIgnoreCompileCommands:false DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:1000
Directive: (default)
matching: *.*
c1 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false BackgroundCompilation:true ReplayInline:false DumpReplay:false DumpInline:false CompilerDirectivesIgnoreCompileCommands:false DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
c2 directives:
inline: -
Enable:true Exclude:false BreakAtExecute:false BreakAtCompile:false Log:false PrintAssembly:false PrintInlining:false PrintNMethods:false BackgroundCompilation:true ReplayInline:false DumpReplay:false DumpInline:false CompilerDirectivesIgnoreCompileCommands:false DisableIntrinsic: BlockLayoutByFrequency:true PrintOptoAssembly:false PrintIntrinsics:false TraceOptoPipelining:false TraceOptoOutput:false TraceSpilling:false Vectorize:false VectorizeDebug:0 CloneMapDebug:false IGVPrintLevel:0 MaxNodeLimit:80000
How Directives are Applied to Code?
A directive is applied to code based on a method matching process. Every method submitted for compilation is matched with a directive in the directives stack.
The process of matching a method with a directive in the directives stack is performed by the CompilerBroker.
The Method Matching Process
When a method is submitted for compilation, the fully qualified name of the method is compared with the matching criteria in the directives stack. The first directive in the stack that matches is applied to the method. The remaining directives in the stack are ignored. If no match is found, then the default directive is applied.
This process is repeated for all methods in a compilation. More than one directive can be applied in a compilation, but only one directive is applied to each method. All directives in the stack are considered active because they are potentially applicable. The key differences between active and applied directives are:
-
A directive is active if it’s present in the directives stack.
-
A directive is applied if it’s affecting code.
Example 2-1 When a Match Is Found
public int exampleMethod(int x){
return x;
}
Based on method-matching criteria, Directive 2
is applied from the following example directive stack:Directive 2:
matching: *.*example*
Directive 1:
matching: *.*exampleMethod*
Directive 0: (default)
matching: *.*
Example 2-2 When No Match Is Found
public int otherMethod(int y){
return y;
}
Based on method-matching criteria, Directive 0
(the default directive) is applied from the following example directive stack:Directive 2:
matching: *.*example*
Directive 1:
matching: *.*exampleMethod*
Directive 0: (default)
matching: *.*
Guidelines for Writing a New Directive
-
No feedback mechanism is provided to verify which directive is applied to a given method. Instead, a profiler such as Java Management Extensions (JMX) is used to measure the cumulative effects of applied directives.
-
The CompilerBroker ignores directive options that create bad code, such as forcing hardware instructions on a platform that doesn't offer support. A warning message is displayed.
-
Directive options have the same limitations as typical command-line flags. For example, the instructions to inline code are followed only if the Intermediate Representation (IR) doesn’t become too large.
Compiler Control and Backward Compatibility
CompileCommand and command-line flags can be used alongside Compiler Control directives.
-
Compiler Control
-
CompileCommand
-
Command-line flags
-
Default values
Example 2-3 Mixing Compiler Control and CompileCommand
-
Compiler Control:
-
Exclude: true
-
BreakAtExecute: false
-
-
CompileCommand:
-
BreakAtExecute: true
-
BreakAtCompile: true
-
-
Default values:
-
Exclude: false
-
BreakAtExecute: false
-
BreakAtCompile: false
-
Log: false
-
-
Exclude: true
-
BreakAtExecute: false
-
BreakAtCompile: true
-
Log: false