ディレクティブの記述

このトピックでは、コンパイラ・コントロールのオプションと、それらのオプションからディレクティブを記述するステップについて確認します。

コンパイラ・コントロールのオプション

オプションはコンパイルに対する命令です。オプションは、メソッドに応じた精度を提供します。使用可能なオプションはコンパイラによって異なり、特定の値の型を必要とします。

表2-1 共通オプション

オプション 説明 値の型 デフォルト値

Enable

falseに設定された場合、ディレクティブを非表示にし、比較不可とします。このオプションは、オプションの重複を回避するために役立ちます。Enableオプションによる重複の回避を参照してください。

bool

true

Exclude

コンパイルからメソッドを除外します。

bool

false

BreakAtExecute

JVMをデバッグする際、指定したメソッドの開始時に実行を停止するブレークポイントを設定します。

bool

false

BreakAtCompile

JVMをデバッグする際、指定したメソッドの開始時にコンパイルを停止するブレークポイントを設定します。

bool

false

Log

指定したメソッドのみをログに記録します。最初にコマンドライン・オプション-XX:+LogCompilationを設定する必要があります。デフォルト値falseは、コンパイルされたすべてのメソッドをログに記録します。

bool

false

PrintAssembly

外部disassembler.soライブラリを使用して、バイト・コード化されたメソッドおよびネイティブ・メソッド用のアセンブリ・コードを出力します。

bool

false

PrintInlining

インライン化されるメソッドおよびその場所を出力します。

bool

false

PrintNMethods

生成されたnmethodを出力します。

bool

false

BackgroundCompilation

バックグラウンド・タスクとしてメソッドをコンパイルします。バックグラウンド・コンパイルが終了するまで、メソッドはインタプリタ・モードで実行されます。値falseは、フォアグラウンド・タスクとしてメソッドをコンパイルします。

bool

true

ReplayInline

対応するグローバル・オプションと同じCIReplay機能をメソッドごとに有効にします。

bool

false

DumpReplay

対応するグローバル・オプションと同じCIReplay機能をメソッドごとに有効にします。

bool

false

DumpInline

対応するグローバル・オプションと同じCIReplay機能をメソッドごとに有効にします。

bool

false

CompilerDirectivesIgnoreCompileCommands

すべてのCompileCommandを無視します。

bool

false

DisableIntrinsic

メソッド照合基準に基づいて組込みの使用を無効にします。

ccstr

デフォルト値なし

inline

メソッド照合基準に基づいてメソッドのインライン化を強制または防止します。インライン・ディレクティブ・オプションの記述を参照してください。

ccstr[]

デフォルト値なし

表2-2 C2専用オプション

オプション 説明 値の型 デフォルト値

BlockLayoutByFrequency

低頻度の実行ブランチをホット・パスから移動します。

bool

true

PrintOptoAssembly

外部disassembler.soライブラリを使用して、コンパイル後に生成されたアセンブリ・コードを出力します。これにはJVMのデバッグ・ビルドが必要です。

bool

false

PrintIntrinsics

使用される組込みメソッドおよびその場所を出力します。

bool

false

TraceOptoPipelining

パイプライン情報をメソッドごとに追跡します(対応するグローバル・オプションと同様)。低速および高速のデバッグ・ビルドを目的としています。

bool

false

TraceOptoOutput

パイプライン情報をメソッドごとに追跡します(対応するグローバル・オプションと同様)。低速および高速のデバッグ・ビルドを目的としています。

bool

false

TraceSpilling

変数のスピルを追跡します。

bool

false

Vectorize

ベクトル・レジスタ間で並行して計算を実行します。

bool

false

VectorizeDebug

ベクトル・レジスタ間で並行して計算を実行します。これにはJVMのデバッグ・ビルドが必要です。

intx

0

CloneMapDebug

ベクトル化から生成されたCloneMapを検査できるようにします。これにはJVMのデバッグ・ビルドが必要です。

bool

false

IGVPrintLevel

OracleのHotspotのIdeal Graphic Visualizer (IGV)に出力されるコンパイラ・グラフのポイントを指定します。値が高いことは粒度が高いことを意味します。

intx

0

MaxNodeLimit

単一のメソッドのコンパイル時に使用するノードの最大数を設定します。

intx

80000

値の型ccstrはメソッド・パターンです。コンパイラ・ディレクティブのメソッド・パターンの記述を参照してください。

デフォルト・ディレクティブは、コンパイラ・オプションのデフォルト値を提供します。デフォルト・ディレクティブとはを参照してください。

ディレクティブ・ファイルの記述

個々のコンパイラ・ディレクティブは、ディレクティブ・ファイルに記述します。アクティブなディレクティブのスタックに追加できるのはディレクティブ・ファイルのみで、個々のディレクティブは追加できません。

  1. .json拡張子を使用してファイルを作成します。ディレクティブ・ファイルは、JSON構文のサブセットを使用して記述し、若干の追加と変更を行います。
  2. 作業のベースとなるテンプレートとして次の構文を追加します。
    [  //Array of Directives
        {   //Directive Block
            //Directive 1
        },
        {   //Directive Block
            //Directive 2
        },
    ]

    このテンプレートの構成要素は次のとおりです。

    ディレクティブの配列
    • ディレクティブ・ファイルはディレクティブ・ブロックの配列を格納します。この配列は1対のカッコ([])で示されます。

    • ファイルに含まれるディレクティブ・ブロックが1つのみの場合、カッコはオプションです。

    ディレクティブ・ブロック
    • 1つのブロックは1対のカッコ({})で示されます。

    • 1つのブロックには1つのディレクティブが含まれます。

    • ディレクティブ・ファイルには任意の数のディレクティブ・ブロックを含めることができます。

    • ブロックはカンマ(,)で区切ります。

    • 配列内の最後のブロックに続くカンマはオプションです。

    ディレクティブ
    • 各ディレクティブはディレクティブ・ブロック内に存在する必要があります。

    • ディレクティブ・ファイルに複数のディレクティブ・ブロックが含まれている場合、そのファイルには複数のディレクティブを含めることができます。

    コメント
    • 単一行のコメントの前に2つのスラッシュ(//)を付けます。

    • 複数行のコメントは使用できません。

  3. テンプレートでディレクティブ・ブロックを追加または削除して、ディレクティブ・ファイルに含めるディレクティブの数と一致させます。
  4. ディレクティブ・ブロックごとに1つのコンパイラ・ディレクティブを記述します。コンパイラ・ディレクティブの記述を参照してください。
  5. 必要に応じてディレクティブ・ブロックを整理しなおします。ファイル内のディレクティブの順序は重要です。記述されたディレクティブが配列の先頭に近いほど、優先度が高くなります。詳細は、ディレクティブ・スタック内のディレクティブの順序およびコードへのディレクティブの適用を参照してください。
次の例は、2つのコンパイラ・ディレクティブを含む作成済のディレクティブ・ファイルを示しています。
[  //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,
        },
    },
]

コンパイラ・ディレクティブの記述

コンパイラ・ディレクティブをディレクティブ・ファイル内に記述する必要があります。ディレクティブ・ファイルに記述する個々のコンパイラ・ディレクティブごとに、次のステップを繰り返します。

個々のコンパイラ・ディレクティブは、ディレクティブ・ファイルのディレクティブ・ブロック内に記述します。ディレクティブ・ファイルの記述を参照してください。
  1. 作業のベースとなるテンプレートとして次のコード・ブロックを挿入して、個々のコンパイラ・ディレクティブを記述します。このコード・ブロックはディレクティブ・ブロックです。
        {
            match: [],
            c1: {
                //c1 directive options
            },
            c2: {
                //c2 directive options
            },
            //Directive options applicable to all compilers
        },
  2. メソッド・パターンの配列にmatch属性を指定します。コンパイラ・ディレクティブのメソッド・パターンの記述を参照してください。
    次に例を示します。
            match: ["java*.*", "oracle*.*"],
  3. カンマで区切られたディレクティブ・オプションのブロックにc1属性を指定します。これらのオプションはc1コンパイラに対して有効になります。
    次に例を示します。
            c1: {
                Enable: true,
                Exclude: true,
                BreakAtExecute: true,
            },
  4. カンマで区切られたディレクティブ・オプションのブロックにc2属性を指定します。このブロックでは、共通のコンパイラ・オプションとc2専用のコンパイラ・オプションを併用できます。
    次に例を示します。
            c2: {
                Enable: false,
                MaxNodeLimit: 1000,
            },
  5. ディレクティブの末尾に、すべてのコンパイラに適用するオプションを指定します。これらのオプションは、共通ブロックの範囲内に記述されているものとみなされます。オプションはカンマで区切ります。
    次に例を示します。
            BreakAtCompile: true,
            DumpReplay: true,
  6. 次のステップを実行して、ファイルをクリーン・アップします。
    1. ディレクティブ・オプションの重複を確認します。競合が発生した場合は、最後に出現するオプションが優先されます。競合は通常、共通ブロックとc1ブロックまたはc2ブロックとの間で発生します(c1ブロックとc2ブロックとの間ではありません)。
    2. c2専用ディレクティブ・オプションを共通ブロックに記述しないようにします。共通ブロックは共通オプションとc2専用オプションの組合せを受け入れることができますが、コマンド・ブロック内のc2専用オプションはc1コンパイラに影響を及ぼさないため、この方法でディレクティブを構成するのは無意味です。かわりに、c2専用オプションをc2ブロック内に記述してください。
    3. c1またはc2属性に対応するディレクティブ・オプションがない場合は、そのコンパイラに対する属性と値の構文を省略します。
次の例は、前述の例に基づく最終的なディレクティブを示しています。
    {
        match: ["java*.*", "oracle*.*"],
        c1: {
            Enable: true,
            Exclude: true,
            BreakAtExecute: true,
        },
        c2: {
            Enable: false,
            MaxNodeLimit: 1000,
        },
        BreakAtCompile: true,
        DumpReplay: true,
    },
JSON形式のディレクティブ・ファイルでは、構文において次の変更が許容されます。
  • 配列およびオブジェクトでは、後に続く余分なカンマはオプションです。

  • 属性は文字列であり、必要に応じて引用符で囲まれます。

  • 配列に含まれる要素が1つのみの場合、カッコはオプションです。

したがって、次の例は、有効なコンパイラ・ディレクティブを示しています。
    {
       "match": "*Concurrent.*",
        c2: {
            "Exclude": true,
        }
    },

コンパイラ・ディレクティブのメソッド・パターンの記述

ccstrはメソッド・パターンであり、正確に記述することも、ワイルドカード文字で一般化することもできます。一致度の高いどのJavaコードに、付随するディレクティブ・オプションを適用するか、またはどのJavaコードをインライン化するかを指定できます。

メソッド・パターンを記述するには、次のようにします。
  1. package/class.method(parameter_list)の構文を使用して、メソッド・パターンを記述します。ワイルドカード文字を使用してメソッド・パターンを一般化する場合は、ステップ2を参照してください。
    次の例は、この構文を使用するメソッド・パターンを示しています。
    java/lang/String.indexOf()
    その他の書式設定スタイルも使用できます。これにより、CompileCommandなどの以前のメソッド照合手段との下位互換性が確保されます。前述の例に代わる有効な書式設定には次のものが含まれます。
    • java/lang/String.indexOf()
    • java/lang/String,indexOf()
    • java/lang/String indexOf()
    • java.lang.String::indexOf()
    最後の書式設定スタイルは、HotSpot出力と一致します。
  2. ワイルドカード文字(*)を、メソッド・パターンの一部を一般化する場所に挿入します。
    次の例は、ステップ1のメソッド・パターンの例を適切に一般化したものを示しています。
    • java/lang/String.indexOf*
    • *lang/String.indexOf*
    • *va/lang*.*dex*
    • java/lang/String.*
    • *.*
    一般化の度合いが増すほど、精度が低くなります。より多くのJavaコードが、メソッド・パターンと潜在的に一致するようになります。そのため、ワイルドカード文字(*)は慎重に使用することが重要です。
  3. Java仕様に従って、メソッド・パターンのシグニチャ部分を変更します。シグニチャの照合は厳密である必要があります。そうでないと、シグニチャがワイルドカード文字(*)にデフォルト設定されます。省略されたシグニチャもワイルドカード文字にデフォルト設定されます。シグニチャにワイルドカード文字を含めることはできません。
  4. オプション: inlineディレクティブ・オプションを伴うメソッド・パターンを記述する場合、追加の文字をメソッド・パターンの前に付ける必要があります。インライン・ディレクティブ・オプションの記述を参照してください。

インライン・ディレクティブ・オプションの記述

inlineディレクティブ・オプションの属性は、接頭辞つきの特殊コマンドを使用したメソッド・パターンの配列を必要とします。これにより、インライン化するメソッド・パターンとインライン化しないメソッド・パターンを指定します。

  1. ディレクティブの共通ブロック、c1ブロックまたはc2ブロックに、inline: と記述します。
  2. 慎重に順序付けたメソッド・パターンの配列を追加します。最初に一致したメソッド・パターンの接頭辞つきコマンドが実行されます。配列内の残りのメソッド・パターンは無視されます。
  3. +の接頭辞を付けると、一致するJavaコードのインライン化が強制されます。
  4. -の接頭辞を付けると、一致するJavaコードのインライン化が回避されます。
  5. オプション: インライン化動作を複数のメソッド・パターンに適用する必要がある場合、ステップ1から4を繰り返して、複数のinline文を記述します。複数のメソッド・パターンが含まれる単一の配列を記述しないでください。
次の例は、inlineディレクティブのオプションを示しています。
  • inline: ["+java/lang*.*", "-sun*.*"]
  • inline: "+java/lang*.*"

Enableオプションによる重複の回避

Enableオプションを使用して、ディレクティブの側面を非表示にし、ディレクティブ間の重複を回避できます。

次の例では、コンパイラ・ディレクティブのc1属性は同一です。
[
    {
        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,
        },
    },
]
次の例は、この望ましくないコード重複をEnableオプションでどのように解消するかを示しています。Enableは、ブロック・ディレクティブを非表示にし、それらを比較不可とします。
[
    {
        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
        },
    },
]
通常、最初の一致ディレクティブがメソッドのコンパイルに適用されます。Enableオプションは、このルールに対する例外を提供します。1つ目または2つ目のディレクティブ内のc1によって通常コンパイルされるメソッドは、3つ目のディレクティブ内のc1ブロックによってコンパイルされるようになりました。3つ目のディレクティブのc2ブロックには到達できません。これは、1つ目および2つ目のディレクティブ内のc2ブロックが優先されるためです。