kagamihogeの日記

kagamihogeの日記です。

アトラス作品ファン交流会の眼鏡祭  シン・メガネ(スーパー眼鏡祭F完結編)(2016/11/12)に行ってきた

11/12 シン・メガネ(スーパー眼鏡祭F完結編) - TwiPla に行ってきました。当日の様子はtwitterハッシュタグ #眼鏡祭1112 で追うことが出来ます。

眼鏡祭はペルソナ中心アトラス作品ファンのオフ会

当日は快晴で気温も落ち着いており、終日穏やかで過ごしやすい一日となりました。当日の朝に電車遅延が若干懸念されたものの大きな問題にならず関係者一同は皆ホッとしていたことと思います。

会場は眼鏡祭常連にいつもの場所であるキリストンカフェ 東京を貸切っての開催です。参加者は約250人近くにもなり、今回も活況を呈しておりました。眼鏡祭は常連も多いのですが、ペルソナ5が発売されて数ヶ月といったタイミングであり、初めての参加者の割合もいつも通りチラホラと見られました。

眼鏡祭の特徴はコスプレOKなオフ会

眼鏡祭の雰囲気を大まかにつかむには、以下のコスプレ参加者による全体集合写真を見るのが良いです。

コスプレするかしないかは個人の自由ですが、参加者の7~8割は何らかのコスプレをしています。アトラス作品縛りのコスプレでこれだけの人数が集まるのは相当レアな光景なこともあり、毎回圧倒させられます。

今回のコスプレの比率は、やはりなんといってもペルソナ5が最大勢力でした。P5主人公ことジョーカーの私服・制服・怪盗衣装に囚人服は当然のこと。竜司君にアン殿など怪盗団はそろい踏みでした。あとはベルベットルームの双子や川上先生、武見女医、ガンショップの岩井などCOOPの人たち。しかしなんといってもやたらいた佐倉惣治郎が皆の心に残ったんではないでしょうか。

ただしコスプレイベントではなく、あくまででもコスプレ可能なオフ会

上記のように眼鏡祭は見た目にも派手なコスプレがどうしても眼を惹きますが、趣旨はあくまでもゲームプレイヤー同士の交流をするオフ会です。そのため、コスプレの撮影に関しては本人の許可を取ること。また、SNSなどのアップロードにも本人の許可を取ること。人が多いので自撮り棒は使わず誰かに依頼すること、など幾つかルールが定められています。

他にもいくつか細かいルールがありますが、どれも常識的な範疇に収まるものなので基本的にはそれほど意識することはありません。前提条件として、アルコールを提供するから20歳以上であり、皆大人なので節度を守った楽しい飲み会にしましょう、というのがこれらルールの根底にあるようです。

ネタバレには出来る限り最大限の配慮がされていた

さて、200人オーバーも集まるとなると気になるのはネタバレの扱い。発売日が2016年9月15日でクリア時間は話を聞いているとおおむね100時間前後くらいのようです。これを考慮すると今回の開催日は絶妙でしたが、しかしまだまだ未クリアな人も多数おり、結構判断が難しいところに見えました。しかし、100%防ぐのは不可能にしてもかなりの程度防止する仕組みが準備されており、これはTECHNICALで素晴らしかったです。

まず、会場は大きく二つに分けてネタバレOK・NGフロアとなりました。もちろん、何か仕切りがあるわけではないので往来は自由です。つまり、最初に来場して席に着くテーブルは間違いなくネタバレOK・NGのどちらかしかいないことになります。

次に、参加者は名前とtwitter等のidを書いた札を首からぶらさげます。これの色が青はスタッフ、黒はネタバレOK、赤はネタバレNG、という色識別になりました。私はまだクリアしていないから体感したんですが、この仕組みは強力でした。

何故かというと、黒札の人はこちらが赤札なのをチラッと見ると会話内容に配慮してくれるためです。プレイ済みな人だからこそネタバレされるのがつまらないことを知っている、ということなんでしょう。

勿論、クリアしていたらもっと楽しく会話出来たことは当然のことです。やはり、ネタバレへの配慮は必要なのだとしても誰はばかることなくオープンに盛り上がりたい、と思うのは自然なことでしょう。

一人で行っても楽しめるかどうか

私も元々は一人だけで参加した類なので、これだけ巨大なオフ会に参加するのに二の足踏む気持ちは大変良く分かります。とはいえ、周囲は全員、皆多かれ少なかれオタクです。朝から晩までゲームアニメマンガの話ずっとしていても何も言われない場ですが、皆そういう欲望をどこかして持っているものです。真昼間から、コスプレして、飲んで、騒ぐ。眼鏡祭は、DJがBGM流してくれてる以外、特に決まった催しものがないですが、そのシンプルな内容に皆惹かれて集まってきているようです。

運営チームの皆さんおつかれさまです

眼鏡祭はイベント会社を使っているわけではなく、会場と飲食提供を除けば、有志のスタッフで回しています。

上記は一例として、マンパワーが大量にいる力仕事の会場設営およびどうしても細かい配慮が必要とされる女子更衣室関連の方のtweetを引用させていただきました。これら目に付くもの以外にもあれやこれや大変な苦労が裏側では確実にあるわけで、毎回本当に頭が上がりません。

最後になりましたが、主催のマソーさん並びに運営スタッフの方々、今回の参加者の皆さんと一・二・三次会で自分と話してくれた人たち、それとこの日記で眼鏡祭の雰囲気を伝えるために勝手ながらtweet引用させて頂いた方々、先日はありがとうございました。

今後のイベントなどリンク

JEP 296: Consolidate the JDK Forest into a Single Repositoryをテキトーに訳した

http://openjdk.java.net/jeps/296 をテキトーに訳した。

JEP 296: Consolidate the JDK Forest into a Single Repository

Author   Joseph D. Darcy
Owner   Joe Darcy
Created 2016/10/07 18:42
Updated 2016/10/26 23:34
Type    Infrastructure
Status  Candidate
Component   infrastructure/build
Scope   Implementation
Discussion  jdk9 dash dev at openjdk dot java dot net
Effort  M
Duration    S
Priority    3
Reviewed by Brian Goetz, Mikael Vidstedt
Release 10
Issue   8167368

Summary

多数のJDKリポジトリ群を単一リポジトリに統合して開発の簡易化と効率化を行います。

Non-Goals

JDKへのFXのソース追加は本JEPには含めません。

Motivation

長年の間に、JDKの完全なコードベースは多数のMercurialリポジトリに分割されてきました。JDK 9では8個のリポジトリroot, corba, hotspot, jaxp, jaxws, jdk, langtools, and nashornがあります。

複数リポジトリには何点かの利点がある一方で様々な欠点があり、あるべきソースコード管理オプションサポートが貧弱になっています。とりわけ、内部的に依存関係のあるチェンジセットの複数リポジトリにまたがるアトミックなコミットが出来ません。たとえば、いま単一のバグフィックスあるいはRFEのコードがjdkとhotspotリポジトリの両方を触るとした場合、両リポジトリへの変更を個々のリポジトリに対してアトミックに実行出来ません。複数リポジトリ変更はよくあることで、1,100以上のバグidがリポジトリで再利用されています。この1,100個という数字は論理的なリポジトリ横断バグ数の下限に過ぎず、その理由はエンジニアによっては異なるリポジトリへのプッシュに異なるバグidを使用しているためです。

上述のMercurialリポジトリの分断とエンジニアの作業単位のミスマッチにより近代的なソースコード管理管理の主なメリットである、個々のファイルではなくファイルのチェンジセットのトラッキング、が薄められています。その結果、SCMトランザクションと論理的なトランザクションとのミスマッチはMercurial bisectなどのツール使用を困難にしています。

JDK全体とは別の開発サイクルを個々のリポジトリが持つわけではありません。すべてのリポジトリJDKのプロモーションサイクルに歩調を合わせます。多数のリポジトリは新規の開発者に対する障壁となり、"get source"スクリプトなどの回避策を取らせることになりました。

Description

これらの問題解決のため、統合リポジトリのプロトタイプが作られました。プロトタイプは以下で利用可能です。

http://hg.openjdk.java.net/jdk9/consol-proto/

プロトタイプ作成に使われた変換スクリプトのいくつかはunify.zipでアタッチされています。

このプロトタイプでは、個々のファイルレベルのヒストリーを保持する自動変換スクリプトで8個のリポジトリを単一リポジトリに統合しており、JDKプロモーションをマークするのに使われるタグで統合コード群を同期化しています。チェンジセットのコメントと生成日も維持しています。

プロトタイプでは異なるコード整理のためのレベルを導入しています。統合リポジトリでは、Javaモジュールのコードは基本的には単一トップレベルsrcディレクトリ下に結合しています。たとえば、現在のJDKリポジトリには以下のようなモジュールベースのディレクトリがあります。

$ROOT/jdk/src/java.base
...
$ROOT/langtools/src/java.compiler
...

統合リポジトリでは以下のように編成されます。

$ROOT/src/java.base
$ROOT/src/java.compiler
...

結果として、リポジトリルートからのモジュール内のソースファイルの相対パスは統合後はsrcディレクトリ下に維持されます。

テストディレクトリに対してはやや異なる再編成策を計画しています(ただし実装は未完成)。*1

$ROOT/jdk/test/Foo.java
$ROOT/langtools/test/Bar.java

上記から以下にします。

$ROOT/test/jdk/Foo.java
$ROOT/tests/langtools/Bar.java

まだプロトタイプであるため、不完全な部分がありますが改善は可能です。$ROOT/jdk, $ROOT/langtoolsなどのディレクトリに残存ファイルがまだありますが、それらのファイルは以降の作業で再編成を予定しています。HotSpot C/C++のソースはモジュール化したJavaコードと共に共有srcディレクトリに移動します。

jtreg設定ファイルのアップデートサポートは現在作業中です(JDK-8165187)。

Alternatives

代案の一つとしては単に現行のリポジトリセットのままにしておくことが挙げられます。単一リポジトリ以降時にはリポジトリのヒストリーの全てあるいはいくつかが消失する可能性がありましたが、that was rejected*2リポジトリの中核セブセットを統合することも考えられましたが、単一リポジトリの明快さという点で無しになりました。

Testing

ファイルの中身の検証には、あるタグの旧リポジトリの内容とそれに対応する同じタグの統合リポジトリの内容を検証するスクリプトを使用しています。最新のJDK 9のタグでは、同一タグの統合リポジトリと旧リポジトリのビルドが比較されており、少数の説明がつく差異のみが存在します。

Risks and Assumptions

上述のテストによりファイル衝突とビルド失敗の重大なリスクを軽減すべきです。統合に必要な作業の大部分はプロトタイプ上に完成していますが、JDK 10でオープンにしたいと考えているその時までに各種の小規模サポート機能は準備出来ないかもしれません。統合前後のコードベースはMercurial senseでは関連がありません。チェンジセットのエクスポートとインポートとは対照的に、foward-portとback-portのためにはDiffs (with suitably massaged paths)を使う使う必要がああります。*3

*1:An analogous but less aggressive reorganization is planned が原文。良い日本語浮かばなかった。

*2:何がrejectされたのか良く分からん…

*3:Risks and Assumptionsの項は良く分からんくて全般的に訳が微妙。

JEP 295: Ahead-of-Time Compilationをテキトーに訳した

http://openjdk.java.net/jeps/295 をテキトーに訳した

JEP 295: Ahead-of-Time Compilation

Owner    Vladimir Kozlov
Created 2016/09/15 01:20
Updated 2016/10/27 19:50
Type    Feature
Status  Targeted
Component   hotspot/compiler
Scope   Implementation
Discussion  hotspot dash compiler dash dev at openjdk dot java dot net
Effort  M
Duration    M
Priority    1
Reviewed by John Rose, Mikael Vidstedt
Endorsed by John Rose
Release 9
Issue   8166089

Summary

仮想マシンの起動前にJavaクラスをネイティブコードにコンパイルします。

Goals

  • ピーク時パフォーマンスへの影響を最小限に留めつつ、小・大規模双方のJavaアプリケーションで開始時間を改善します。
  • ユーザの作業手順の変更はなるべく最小限に抑えます。

Non-Goals

コンパイル済みコードの保存およびロードを行う公開ライブラリ的なメカニズムの提供は行いません。

Motivation

JITコンパイラは高速ですが、JITが完全にウォームアップするのに長時間を要するほど大規模なJavaプログラムとなる場合があります。低頻度使用のJavaメソッドは一度もコンパイルされない可能性があり、インタープリタ実行が繰り返されるとパフォーマンス悪化の原因となる可能性が潜在的に存在します。

Description

初期リリースではサポート対象となるモジュールはjava.baseのみとします。これは問題空間を限定するためで、その理由はjava.baseJavaコードは周知のもので、かつ、一連の内部的なテストを実行可能なためです。任意のその他のJDKやユーザーコードのAOTコンパイルは試験的なものです。

java.baseモジュールにAOTを適用するには、ユーザはモジュールをコンパイルしてJDKインストールライブラリにコピーするかJavaコマンドラインで指定します。その点以外は、AOTコンパイルされたコードの使用はエンドユーザに対して完全に透過的です。

AOTコンパイルは新規ツールのjaotcで行います。

jaotc --output libHelloWorld.so HelloWorld.class
jaotc --output libjava.base.so --module java.base

コード生成のバックエンドにはGraalを使用します。

JVM開始およびAOT初期化中に、コードは既知の場所もしくはコマンドラインのAOTLibraryフラグの指定場所から共有ライブラリの参照を試行します。もし共有ライブラリが存在する場合、それが使われます。もし共有ライブラリが見つからない場合、AOTはそのJVMインスタンスでは無効になります。

java -XX:AOTLibrary=./libHelloWorld.so,./libjava.base.so HelloWorld

java.baseにAOTライブラリをインストールしてビルドする方法を指定する新規のAOTフラグとjaotcフラグは以降のサブセクションで示します。

AOTコンパイル済みのコードに対して使われるコンテナフォーマットは共有ライブラリです。JDK 9では共有ライブラリフォーマットがELFLinux/x64のみサポートします。AOTライブラリのAOTコンパイル済みコードは、既存のCodeCacheの拡張としてJVMは扱います。

Javaクラスがロードされる時、AOTライブラリ内に対応するAOTコンパイル済コードがあればJVMはそれを参照し、Javaメソッドディスクリプタからリンクを貼ります。AOTコンパイル済コードは通常のJITコンパイルコードと同様のnvocation/deoptimization/unloadingルールに従います。

ソースコードの変更やクラス変換および再定義などにより、クラスバイトコードは変更可能なため、JVMはそうした変更を検出し、もしバイトコードがミスマッチとなる場合はAOTコンパイル済コードを除去する必要があります。これはclass fingerprintingで実現します。AOTコンパイル時に各クラスごとのfingerprintを生成して共有ライブラリのデータセクションに保存します。その後、クラスロード時にそのクラスにAOTコンパイル済コードがあると、現在のバイトコード用のfingerprintが共有ライブラリ内に保存されているものと比較されます。ミスマッチの場合、対象クラスのAOTコードは使われません。

AOT usage

AOTコンパイルの実行にはjaotcツールを用います。ツールはjavac同様にJavaインストールの一部です。

jaotc --output libHelloWorld.so HelloWorld.class

次に、アプリケーション実行時に生成したAOTライブラリを指定します。

java -XX:AOTLibrary=./libHelloWorld.so HelloWorld

今回のリリースではAOTコンパイル時と実行時に同一のJavaランタイム設定を使うようにして下さい。例えば、

jaotc -J-XX:+UseParallelGC -J-XX:-UseCompressedOops --output libHelloWorld.so HelloWorld.class 
java -XX:+UseParallelGC -XX:-UseCompressedOops -XX:AOTLibrary=./libHelloWorld.so HelloWorld

同一のJDKビルド種類(product or debug)を使用してください*1

ランタイム設定はAOTライブラリ内に記録されて、実行時にライブラリがロードされる際に検証されます。検証失敗時にはそのAOTライブラリは使われず、JVMの実行は継続するか、-XX:+UseAOTStrictLoading指定時には終了します。

JVM開始中にAOT初期化コードは既知の場所か-XX:AOTLibraryオプションが指定するライブラリ内から共有ライブラリを参照します。共有ライブラリがある場合、それが使われます。もし共有ライブラリが見つからない場合、AOTはそのJVMインスタンス実行では無効になります。

AOTライブラリは--compile-for-tieredで制御する二つのモードでコンパイルが可能です。

  • Non-tiered AOTコンパイル済みコードは、静的コンパイルをしたC++コードのような振る舞いとなり、プロファイリング情報は収集されずJITコンパイルは発生しません。
  • Tiered AOTコンパイル済みコードはプロファイリング情報を収集します。このプロファイリングはC1メソッドがTier 2でコンパイルするsimple profilingのと同じです。AOTメソッドがAOT実行スレッショールドにヒットすると、そのメソッドは完全なプロファイリング情報を収集するためにまずC1 at Tier 3で再コンパイルされます。これはC2 JITコンパイルに必要で、最適化コードを生成してピーク時アプリケーションパフォーマンスを出すために行われます。

完全プロファイリングのオーバーヘッドは、とりわけjava.baseなどのモジュールのメソッドでは、すべてのメソッドに適用するには大きすぎるため、Tier 3での再コンパイルのためには更に別のステップが必要です。ユーザーアプリケーションで、Tier 3相当のプロファイリングでAOTコンパイルを行えるようにするかもしれませんが、JDK 9ではサポートしません。

java.baseメソッドのJITコンパイルはピークパフォーマンスを得るのが望ましいため、java.baseの論理コンパイルモードはtiered AOTです。特定シナリオ下ではnon-tiered AOTコンパイルが適しています。これには予測可能な振る舞いを要求するアプリケーションや、ピークパフォーマンスよりもフットプリントの方が重要な場合や、動的なコード生成を許可しないシステムが該当します。こうしたケースの場合、AOTコンパイルはアプリケーション全体で必要であり、JDK 9で試験運用を行います。

AOTライブラリセットは異なる実行環境向けの生成が可能です。特定のランタイム設定用に生成されたjava.baseAOTライブラリに対するwell-knownな名前をJVMは解釈します*2。$JAVA_HOME/libディレクトリを参照して現在のランタイム設定に対応するライブラリをロードします。

-XX:-UseCompressedOops -XX:+UseG1GC :       libjava.base.so
-XX:+UseCompressedOops -XX:+UseG1GC :       libjava.base-coop.so
-XX:-UseCompressedOops -XX:+UseParallelGC : libjava.base-nong1.so
-XX:+UseCompressedOops -XX:+UseParallelGC : libjava.base-coop-nong1.so

以下のJavaモジュール用のAOTライブラリ名をJVMは受け付けますが、これらのコンパイル・インストール・使用は試験運用です。

jdk.compiler 
jdk.scripting.nashorn 
jdk.vm.ci 
jdk.vm.compiler

Steps to generate and use an AOT library for the java.base module

java.baseモジュールのコンパイルにはjaotcを使います。全メソッド(約50000メソッド)のコンパイル用にデータを保持するため巨大なヒープを必要とします。

jaotc -J-XX:+UseCompressedOops -J-XX:+UseG1GC -J-Xmx4g --compile-for-tiered --info --compile-commands java.base-list.txt --output libjava.base-coop.so --module java.base

java.baseのいくつかのメソッドはコンパイルに失敗するため--compile-comandsオプションで除外されています。

cat java.base-list.txt

# jaotc: java.lang.StackOverflowError
exclude sun.util.resources.LocaleNames.getContents()[[Ljava/lang/Object;
exclude sun.util.resources.TimeZoneNames.getContents()[[Ljava/lang/Object;
exclude sun.util.resources.cldr.LocaleNames.getContents()[[Ljava/lang/Object;
exclude sun.util.resources..*.LocaleNames_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.util.resources..*.LocaleNames_.*_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.util.resources..*.TimeZoneNames_.*.getContents\(\)\[\[Ljava/lang/Object;
exclude sun.util.resources..*.TimeZoneNames_.*_.*.getContents\(\)\[\[Ljava/lang/Object;
# java.lang.Error: Trampoline must not be defined by the bootstrap classloader
exclude sun.reflect.misc.Trampoline.<clinit>()V
exclude sun.reflect.misc.Trampoline.invoke(Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;
# JVM asserts
exclude com.sun.crypto.provider.AESWrapCipher.engineUnwrap([BLjava/lang/String;I)Ljava/security/Key;
exclude sun.security.ssl.*
exclude sun.net.RegisteredDomain.<clinit>()V

AOTライブラリを生成したら-XX:AOTLibraryオプションでアプリケーション実行時に指定します(デフォルトではjavaはG1とJDK 9のcompressed oopsを使用するため、このフラグを指定する必要はありません)。

java -XX:AOTLibrary=./libjava.base-coop.so,./libHelloWorld.so HelloWorld

もしくは、生成したAOTライブラリをJDKインストールディレクトリにコピーします(ディレクトリのパーミッションを調整する必要があるかもしれません)。

cp libjava.base-coop.so $JAVA_HOME/lib/

上記の場合、コマンドラインで指定しなくても自動的にロードされます。

java -XX:AOTLibrary=./libHelloWorld.so HelloWorld

ライブラリサイズの縮小にはAOTライブラリから未使用シンボルの削除(strip)を検討してください。

New run-time AOT flags

-XX:+/-UseAOT

AOTコンパイル済みファイルを使います。デフォルトはONです。

-XX:AOTLibrary=<file>

AOTライブラリファイルのリストを指定します。コロン(:)あるいは(,)でそれぞれのライブラリエントリを区切ります。

-XX:+/-PrintAOT

使われるAOT klassesとメソッドを表示します。

診断に利用可能なフラグはもう一つあります(-XX:+UnlockDiagnosticVMOptionsフラグの指定が必要)。

-XX:+/-UseAOTStrictLoading

AOTライブラリの持つランタイム設定が現在のランタイム設定とマッチしない場合JVMは終了します。

JVMランタイムはJEP 158: Unified JVM Loggingで統合される以下のUnified Logging AOTタグを持ちます。

aotclassfingerprint

クラスのfingerprintがAOTライブラリに記録されているfingerprintとマッチしない場合にログを生成します。

aotclassload

対応するクラスデータがAOTライブラリ内に見つかった場合にログを生成します。

aotclassresolve

AOTコンパイル済コードからクラス解決のためのリクエストの成功・失敗ログを生成します。

jaotc: The Java Ahead-Of-Time compiler

jaotcコンパイルjavaメソッドに対してネイティブコードを生成するjava静的コンパイラです。裏側のコード生成にはGraal、.soAOTライブラリに生成にはlibelfを使用します。

このツールはjava installationの一部でjavacと同様な使い方をします。

jaotc <options> <--module name>

もしくは、

jaotc <options> <list of classes or/and jar files>

以下のjaotcフラグが使用可能です。

--module <name>

コンパイルを行うためのモジュール。

--module-path <path>

アプリケーションモジュールの参照先指定。未指定の場合JDKインストールディレクトリを参照します。

--output <file>

出力ファイル名。デフォルト名は"unnamed.so"です。

--compile-commands <file>

コンパイルコマンドにはファイル名を指定します。

exclude sun.util.resources..*.TimeZoneNames_.*.getContents\(\)\[\[Ljava/lang/Object; 
exclude sun.security.ssl.* 
compileOnly java.lang.String.*

AOTは今のところ二つのコンパイルコマンドを使用可能です。

exclude       - exclude compilation of specified methods 
compileOnly   - compile only specified methods

クラスとメソッドの指定には正規表現を使います。

--compile-for-tiered

tieredコンパイルでプロファイリングコードを生成します。デフォルトではプロファイリングコードは生成されません。

--classpath <path>

ユーザクラスファイルの参照先を指定します。

--threads <number>

コンパイルに用いるスレッド数。デフォルト値はmin(16, available_cpus)です。

--ignore-errors

クラスロード中にスローされる全ての例外を無視します。デフォルトでは、クラスロードが例外をスローする場合はコンパイルを終了します。

--exit-on-error

コンパイルエラー時に終了します。デフォルトでは、失敗したコンパイルはスキップされてそれ以外のメソッドのコンパイルは続行します。

--info

コンパイルフェーズに関する情報を表示します。

--verbose

--infoフラグ有効時にコンパイルフェーズに関するより詳しい情報を表示します。

--debug

--infoと--verboseフラグ有効時により詳しい情報を表示します。

-J<flag>

JVMランタイムシステムflagディレクトリを渡します。

--help

jaotcのメッセージとフラグを表示します。

AOT limitations in JDK 9

  • JDK 9のAOT初期リリースは64-bit javaの動作する64-bit Linuxシステムのみサポートします。
  • AOTコンパイル結果であるAOT共有ライブラリ(.so)を許可するためのlibelfがシステムにインストールされていること。
  • Javaアプリケーションで使われるAOTコードでは、同一システムもしくは同一設定システムでAOTコンパイルを実行すること。
  • JDK 9の初期リリースではAOTコンパイルがサポートするモジュールはjava.baseに限定されます。
  • 今のところG1とParallel GCのみサポートします。
  • 動的に生成されるクラスとバイトコードラムダ式, invoke dynamic)を使用するjavaコードのコンパイルはしないでください。
  • AOTコンパイルと実行には同一のJavaランタイム設定を使用して下さい。例えば、アプリケーションがAOTコードにParallel GCを使用する場合、jaotcツールでもParallel GC(-Jフラグを使用)して実行してください。

以上の制限は将来のリリースで扱う予定です。

Alternatives

プロファイルもしくはコンパイルの削減は議論され続けてきましたが、議論だけではコードをコンパイルするのにかかる時間を削減できません。別案として、低レベルIRの低速コピーを節約があり、これはさほど複雑では無さそうです(but that seems no less complex)。

Testing

AOT機能に対する新規のAOT jtregテストを開発します。

すべての既存テストがAOT有効化JDKで実行可能かテストします。既に個々のナイトリーテスト設定を実行しています*3

それ以外の設定をAOTコンパイルjava.baseモジュールを用いてAOT有効化JDK環境ですべてのテストを実行します。

Risks and Assumptions

プリコンパイルコードの使用は最適化を損なうコードとなり、結果としてパフォーマンスを下げる可能性があります。パフォーマンステストの結果では、あるアプリケーションではAOTコンパイルコードで改善が見られる一方で、明らかに悪くなるケースもありました。AOT機能はオプトインなため、ユーザアプリケーションでのパフォーマンス悪化は回避可能です。もしユーザがアプリケーション開始時間の低下に直面、あるいは、所定のピークパフォーマンスに達しない場合、-XX:-UseAOTフラグあるいはAOTライブラリの削除でAOTを無効化できます。

Dependences

AOTコンパイラはコード生成のバックエンドにGraalを使用するため、本プロジェクトはJEP 243: Java-Level JVM Compiler Interfaceに依存しています。

本プロジェクトはJDKGraal coreにマージされてLinux/x64ビルドで配布予定です。

*1:It includes the requirement to use the same JDK build variant: product or debug.が原文。色々と揃えてくれ、ってことだと思われるが、良い日本語訳思い浮かばず

*2:JVM knows next well-known names for java.base AOT libraries generated for specific runtime configuration.が原文

*3:This is already done as separate nightly testing configurations.が原文。ある特定の設定については既にナイトリービルドやってます、てこと?