The following topic examines how directives behave and interact.
The default directive is a compiler directive that contains default values for all possible directive options. It is at the bottom of the directives stack and matches every method submitted for compilation.
When you design a new 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:
Although these printouts provide a thorough account of all directive options and their values, certain options are applicable exclusively to thec2
compiler. For a complete list, see Table 2-2.Directive Option Values in New Directives
New directives must specify how they differ from the default directive. If a directive option is not mentioned, then that option retains the value from the default directive.
[ { match: ["*Concurrent.*"], c2: { MaxNodeLimit: 1000, }, Exclude:true, }, ]When you add this directive to the directives stack, the default directive becomes the bottom-most directive of the stack. See How Are Directives Ordered in the Directives Stack? for a description of this process. The printout from the resulting directives stack shows how only the directive options specified in the example differ from the values found 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
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 brokering a match between a method and the directives stack is performed by the CompilerBroker.
The Method Matching Process
When a method is submitted for compilation, its fully qualified name is compared to the matching criteria in the directives stack. The first matching directive in the stack is applied to the method. The remaining directives in the stack are ignored. If no other match is found, then the default directive is applied.
This process is repeated for all methods in a compilation. Therefore, more than one directive could be applied in a compilation, while only one directive is applied per 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 in the following example directive stack,
Directive 0
(the default directive) is applied:
Directive 2: matching: *.*example* Directive 1: matching: *.*exampleMethod* Directive 0: (default) matching: *.*
Other Guidelines
Carefully write the directives’ method-matching criteria. There’s no feedback mechanism to verify which directive is applied to a given method. Instead, a profiler such as 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, instructions to inline code are followed only if the Intermediate Representation (IR) doesn’t become too large.
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