Commands to Work with Directive Files

This topic examines commands and the effects of working with completed directive files.

Compiler Directives and the Command Line

The command line provides an interface to add and print compiler directives while starting a program.

Only one directives file is specifiable from the command line. All directives within that file are added to the directives stack and are immediately active as the program starts. This makes it possible to test the performance effects of directives during a program’s early stages. You’re also free to focus on debugging and developing your program.

Adding Directives Through the Command Line

The command-line option that specifies a directives file is:
XX:CompilerDirectivesFile=file
Include this command-line option when you start a Java program. This is shown in the following example, which starts TestProgram:
java -XX:+UnlockDiagnosticVMOptions -XX:CompilerDirectivesFile=File_A.json TestProgram
  • -XX:+UnlockDiagnosticVMOptions enables diagnostic options. You must enter this before working with directives on the command line.

  • -XX:CompilerDirectivesFile is a type of diagnostic option. It specifies one directives file to add to the directives stack.

  • File_A.json is a directives file. It contains any number of directives, all of which are added to the stack of active directives as the program starts.

  • If File_A.json contains syntax errors or malformed directives, then an error message is displayed and TestProgram does not start.

Printing Directives Through the Command Line

It’s possible to automatically print the directives stack when a program starts or when additional directives are added through diagnostic commands. The command-line option to enable this behavior is:
-XX:+CompilerDirectivesPrint
An example of including this diagnostic command on the command line is:
java -XX:+UnlockDiagnosticVMOptions -XX:+CompilerDirectivesPrint -XX:CompilerDirectivesFile=File_A.json TestProgram 

Compiler Directives and Diagnostic Commands

Diagnostic commands provide an interface to manage which directives are active at runtime. You can add directives to or remove directives from a running program without restarting it.

Crafting a single perfect directives file may take some iteration and experimentation. However, diagnostic commands provide powerful mechanisms for testing different configurations of directives in the directives stack. Diagnostic commands let you add or remove directives without restarting a running program’s JVM.

Getting Your Java Process Identification Number

The first step in testing directives is to find the process identification (pid) number of your running program.

  1. Open a terminal.
  2. Enter the following: jcmd
This command returns a list of every Java process running on your machine, along with their pid numbers. For example, you may see the following information returned about TestProgram:
11084 TestProgram

Adding Directives Through Diagnostic Commands

All directives in a file are added to the directives stack through a single diagnostic command.

Enter the following:
jcmd pid Compiler.directives_add file
An example is:
jcmd 11084 Compiler.directives_add File_B.json
The terminal reports the number of individual directives added. However, if the directives file contains syntax errors or malformed directives, then an error message is displayed, and no directives from the file are added to the stack. There are no changes to the running program.

Removing Directives Through Diagnostic Commands

There are two diagnostic commands that remove directives.

To remove the top-most, individual directive from the directive stack, enter:
jcmd pid Compiler.directives_remove
To clear every directive you added to the directives stack, enter:
jcmd pid Compiler.directives_clear
It’s not possible to specify an entire file of directives to remove, nor is there any other way to remove directives in bulk.

Printing Directives Through Diagnostic Commands

Diagnostic commands are used to print the directives stack of a running program.

A detailed description of the full directives stack is printed each time you enter:
jcmd pid Compiler.directives_print
Example output is shown in What Is the Default Directive?

How Are Directives Ordered in the Directives Stack?

The order directives are written in a file, or added to the stack, is very important. The top-most best-matching directive in the stack receives priority and is applied to code compilation.

Diagrams in this topic illustrate the ordering effects in an example directives stack. There are three directive files in this scenario:

  • File_A contains Directive 1 and Directive 2.

  • File_B contains Directive 3.

  • File_C contains Directive 4 and Directive 5.

The Initial State of the Directives Stack

TestProgram can be started without involving directive files.
  • Enter the following on the command line to start a program without adding any directives:
    java TestProgram
    
  • TestProgram starts without any directives file specified.

  • The default directive is always at the bottom of the directives stack. Figure 2-1 shows the default directive as Directive 0. When you don’t specify a directives file, then the default directive is also the top directive and receives priority.

Figure 2-1 Starting a Program Without Directives

Description of Figure 2-1 follows
Description of "Figure 2-1 Starting a Program Without Directives"
Alternatively, directives can be added to the directives stack when you start TestProgram:
  • Enter the following on the command line to add all directives from File_A.json to the directives stack:
    java -XX:+UnlockDiagnosticVMOptions -XX:CompilerDirectivesFile=File_A.json TestProgram
    
  • Directives are added to the stack in the reverse order they’re written. The top-most directive in the file becomes the top-most directive on the stack.

  • Figure 2-2 shows that the order of directives in the stack, from top to bottom, becomes: [1, 2, 0].

Figure 2-2 Starting a Program with Directives

Description of Figure 2-2 follows
Description of "Figure 2-2 Starting a Program with Directives"

Additions to the Directives Stack

If TestProgram is running, then you must supply additional directives through diagnostic commands:
  • Enter the following to add all directives from File_B to the directives stack:
    jcmd 11084 Compiler.directives_add File_B.json
    
  • Directive 3 is added to the top of the stack. This is the only directive found in File_B.

  • Figure 2-3 shows that the order of directives in the stack becomes: [3, 1, 2, 0].

Figure 2-3 Adding a Directive to a Running Program

Description of Figure 2-3 follows
Description of "Figure 2-3 Adding a Directive to a Running Program"
More directive files can be added through diagnostic commands if TestProgram continues running:
  • Enter the following to add all directives from File_C to the directives stack.
    jcmd 11084 Compiler.directives_add File_C.json
    
  • Figure 2-4 shows that the order of directives in the stack becomes: [4, 5, 3, 1, 2, 0].

Figure 2-4 Adding Many Directives to a Running Program

Description of Figure 2-4 follows
Description of "Figure 2-4 Adding Many Directives to a Running Program"

Removals from the Directives Stack

The top-most directive is removable through diagnostic commands:
  • Enter the following to remove Directive 4 from the stack:
    jcmd 11084 Compiler.directives_remove
    
  • Top directives are removable one at a time by repeating this diagnostic command until only the default directive remains. You can’t remove the default directive.

  • Figure 2-5 shows that the order of directives in the stack becomes: [5, 3, 1, 2, 0].

Figure 2-5 Removing One Directive from the Stack

Description of Figure 2-5 follows
Description of "Figure 2-5 Removing One Directive from the Stack"
There is one mechanism to bulk-remove directives from the directives stack:
  • Enter the following to clear the directives stack:
    jcmd 11084 Compiler.directives_clear
    
  • All directives are removed at one time except the default directive. You can’t remove the default directive.

  • Figure 2-6 shows that only Directive 0 remains in the stack.

Figure 2-6 Removing All Directives from the Stack

Description of Figure 2-6 follows
Description of "Figure 2-6 Removing All Directives from the Stack"