カスタム Java コンパイラまたはバイトコード エージェントがあるとします。
合成メソッド内でバイトコードを「ホスト」するために匿名クラスを生成する必要がない方法で、呼び出しサイトのバイトコードをブートストラップ ハンドラーに渡すことは可能ですか?
つまり、バイトコードを渡したら、できるだけ少ないオーバーヘッドでそれを実行したい (バイトコードが機能するのにちょうどいいスタックとローカル変数配列を既に取得していると仮定して)
カスタム Java コンパイラまたはバイトコード エージェントがあるとします。
合成メソッド内でバイトコードを「ホスト」するために匿名クラスを生成する必要がない方法で、呼び出しサイトのバイトコードをブートストラップ ハンドラーに渡すことは可能ですか?
つまり、バイトコードを渡したら、できるだけ少ないオーバーヘッドでそれを実行したい (バイトコードが機能するのにちょうどいいスタックとローカル変数配列を既に取得していると仮定して)
InvokeDynamic の仕組みは、命令が初めて実行されるときに、適切なブートストラップ メソッドが呼び出されることです。ブートストラップ メソッドによって返される CallSite オブジェクトは、この命令と後続のすべての命令呼び出しで実行されます。毎回メソッドをルックアップするアドホック メソッドよりも、VM がこれをより効率的に処理できるという考え方です。
ただし、これはすべてのバイトコードが実行されるクラス内になければならないという要件を回避するものではありません。これが JVM プラットフォームの仕組みです。ただし、新しいクラスを作成するとオーバーヘッドが発生すると考える理由がわかりません。他のメソッドと同じようにインライン化できます。より大きな懸念は、余分なクラスが原因でコードに割り当てられたメモリのスペースが不足することですが、Java 7 にはそれを支援するためのライブラリ呼び出しもいくつか用意されていると思います。
さて、私はついに必要なものを見つけました:
http://www.docjar.com/html/api/sun/invoke/anon/AnonymousClassLoader.java.html
まだ標準化されておらず、見捨てられる可能性がありますが、より軽いタッチが可能です。
ジョン・ローズは自身のブログで次のように語っています。
https://blogs.oracle.com/jrose/entry/anonymous_classes_in_the_vm
もう 1 つのオプションは、呼び出しバイト コードを MethodHandles に変換し、それをそのまま渡すことです。