前回のの投稿で、Java 8と9ではjava -XX:+PrintCompilation -XX:CompileOnly=xxx
の出力が異なると書きました。
すると、OpenJDK Reviewerである末永さんからヒントをいただきました。
Excluding compileって特徴的ですね。これでHotSpotのソースをgrepして、その箇所をannotateでchangesetを特定すればヒントがあるかもしれません。
— Yasumasa Suenaga (@YaSuenag) 2017年11月21日
こういう形式の出力が大量にあったわけです。
### 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の過程で変更されたことがわかりました!