Fight the Future

Java言語とJVM、そしてJavaエコシステム全般にまつわること

Java 9では"-XX:CompileOnly"は"-XX:CompileCommand=quiet"と組み合わせでおこう

前回のの投稿で、Java 8と9ではjava -XX:+PrintCompilation -XX:CompileOnly=xxxの出力が異なると書きました。

jyukutyo.hatenablog.com

すると、OpenJDK Reviewerである末永さんからヒントをいただきました。

こういう形式の出力が大量にあったわけです。

### Excluding compile: static java.lang.StringLatin1::hashCode
made not compilable on levels 0 1 2 3  java.lang.StringLatin1::hashCode (42 bytes)   excluded by CompileCommand

なので、OpenJDKのjdk9をfind&grepしました。

$ find . -type f -print0 | xargs -0 grep "Excluding"
...
./hotspot/src/share/vm/compiler/compileBroker.cpp:      tty->print("### Excluding %s:%s",
...

compileBroker.cppがこのログを出力しています。ファイル名からしてJITコンパイル時の動作にかかわっていることは間違いなしです。見てみます。

9218:     if (PrintCompilation && !quietly) {
    0:       // This does not happen quietly...
    0:       ResourceMark rm;
    0:       tty->print("### Excluding %s:%s",
    0:                  method->is_native() ? "generation of native wrapper" : "compile",
    0:                  (method->is_static() ? " static" : ""));
    0:       method->print_short_name(tty);
    0:       tty->cr();
    0:     }

hg annotateしたところ、9218と出ています。hg log -vして9218を検索します。

changeset:   9218:96bcdd3a6e79
user:        neliasso
date:        Wed Oct 28 15:44:28 2015 +0100
files:       src/share/vm/compiler/compileBroker.cpp
description:
8140581: Excluding compile messages should only be printed with PrintCompilation
Summary: Use PrintCompilation flag instead
Reviewed-by: kvn

どうやらExcluding compile messagesはPrintCompilationのときのみにする変更があったようです。じゃあ今までどこにどう出てたんでしょうね?まだ私にはわかりません。

Webでこのchangesetを見れます。

jdk9/jdk9/hotspot: 96bcdd3a6e79

さて、if (PrintCompilation && !quietly) {の条件でこの"### Excluding"ログが出るわけです。じゃあ-XX:CompileCommand=quietすれば出なくなるはずと考え、試しました。

$ java \
 -XX:+PrintCompilation \
 -XX:CompileOnly=Demo::workload \
 -XX:CompileCommand=quiet \
 Demo
    119    1       3       Demo::workload (4 bytes)
    119    2       1       Demo::workload (4 bytes)
    119    1       3       Demo::workload (4 bytes)   made not entrant

無事Java 9でも8のときと同じ出力になりました。

Java 8

もともとどうだったのか、コミットの前後を見てもよかったのでしょうがOpenJDKのjdk8を確認してみました。

    if (!quietly) {
      // This does not happen quietly...
      ResourceMark rm;
      tty->print("### Excluding %s:%s",
                 method->is_native() ? "generation of native wrapper" : "compile",
                 (method->is_static() ? " static" : ""));
      method->print_short_name(tty);
      tty->cr();
    }

やはり条件式が違い、if (!quietly) {となっています。8から9の過程で変更されたことがわかりました!