http://openjdk.java.net/jeps/334
JEP 334: JVM Constants API
Author Brian Goetz Owner Vicente Arturo Romero Zaldivar Type Feature Scope SE Status Candidate Component core-libs / java.lang.invoke Discussion amber dash dev at openjdk dot java dot net Blocks JEP 303: Intrinsics for the LDC and INVOKEDYNAMIC Instructions Reviewed by Alex Buckley Endorsed by Brian Goetz Created 2018/05/15 21:52 Updated 2018/11/13 11:31 Issue 8203252
Summary
中核であるクラスファイルとランタイムアーティファクトで名目上の記述(nominal descriptions)*1、ここではコンスタントプールからロード可能な定数、のためのAPIを導入します。
Motivation
すべてのJavaクラスファイルはconstant poolを持ち、ここにバイトコード命令用のオペランドを格納しています。constant poolのエントリは、クラスとメソッドなどのランタイムアーティファクトか文字列と数値などの単純な値、のいずれかを持ちます。これらのエントリは、ldc
命令("load constant")でオペランドとして振る舞うため、loadable constantsと呼ばれています。これらはinvokedynamic
命令のブートストラップメソッドのstatic引数リストにも出てきます。ldc
やinvokedynamic
命令を実行すると、loadable constantは通常のJavaの型であるClass
, String
, int
などの "live" な値に解決されます。
class
ファイルを操作するプログラムはバイトコード命令を扱う必要があり、loadable constantも同様です。ただ、loadable constantsを扱う標準のJava型は不十分です。文字列(CONSTANT_String_info
エントリ)のloadable constantは"live" なString
オブジェクトの生成が単純なので許容範囲内ですが、クラス(CONSTANT_Class_info
エントリ)のloadable constantは"live"なClass
オブジェクトはクラスローディングの正確さと一貫性に依存するため困難を伴います。クラスローディングには多数の環境依存と失敗理由が存在します。要求クラスが存在しない、リクエスト元からアクセス不能、クラスローディングがコンテキストで変化、ロードするクラスに副作用がある、クラスローディングが全く出来ない場合もあります(あるクラスがコンパイル中かjlink
中なのでクラスがまだ無いかロード不能など)。
よって、もし、クラスとメソッドを操作可能で、メソッドハンドルと動的に計算される定数など既知のアーティファクトを減らせれば、 loadable constantsを扱うプログラムはシンプルになります。このために、純粋な名目上の形式(in purely nominal form)を使用します。
- バイトコードのパースと生成ライブラリがシンボリック形式でクラスとメソッドハンドルを記述できることが必須。標準の機構が無い場合、アドホックなやり方に依存せざるを得ず、これにはASMのハンドルなどディスクリプタ型、文字列のタプル(メソッドオーナ、メソッド名、メソッドディスクリプタ)、単一文字列へのアドホック(およびerror-prone)なエンコーディング、などがあります。
- バイトコードのスピニングによって実行する
invokedynamic
のブートストラップ(LambdaMetafactory
など)は、もし"live"なクラスとメソッドハンドルではなくシンボリックドメインで実行可能であれば、よりシンプルになります。 - コンパイラとオフライン変換(
jlink
プラグインなど)は、実行中のVMにロード不能な、クラスとクラスメンバを記述します。コンパイラプラグイン(アノテーションプロセッサなど)も同様にシンボリックターム内にプログラム要素を記述します。
こうした種類のライブラリとツールは、loadable constantsを記述する単一の標準があることで、恩恵を受けられます。
Description
loadable constant各種を記述するための、値ベースなシンボリックリファレンス(value-based symbolic reference)(JVMS 5.1)型を、新規にjava.lang.invoke.constant
パッケージに定義します。シンボリックリファレンスは、クラスローディングやアクセシビリティコンテキストとは別途に、純粋な名目上の形式でloadable constantを記述します。いくつかのクラスはそのクラス自身のシンボリックリファレンスとして振る舞えます(例 String
)。リンク可能な定数用にシンボリックリファレンス型(ClassDesc
, MethodTypeDesc
, MethodHandleDesc
, DynamicConstantDesc
)を定義します。これらの型は定数を記述する名目情報(nominal information)を持ちます。
API仕様のドラフトスナップショットはこちらで、JEP 303に関する詳細情報はcompanion documentにあります。
Dependencies
このJEPは元はJEP 303 (Intrinsics for the LDC and INVOKEDYNAMIC Instructions).のサブ機能でした。現在JEP 303はこのJEPに依存します。
*1:うまい日本語が見つからず怪しい訳語を当てている……