invokedynamic at #shikadriven 2012
TRANSCRIPT
鹿駆動勉強会@能楽堂
5分でわかる!? InvokeDynamic
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
@tan_go238/JVM/ぬる舗/迷子
関西Javaエンジニアの会/京都JAWS-UG
絶賛幽霊部員なう!
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
「InvokeDynamic」で知るべき 3- つのこと
① Javaがどうやって動いているか
② InvokeDynamicの基本
③ JVM上で動作する動的言語
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
Javaの動作原理
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
ソースコードが実行されるまで
Java ClassJVM
Class
ソースコード中間ファイル
(バイナリ)実行
① ② ③
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
ソースコード
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example() { MyObj o = new MyObj(); int i = o.exe(); return silly(o, i);}
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
javap -c -verbose ...
Javaソースコード
Classファイルを解析した結果
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
aload_0 とか invokevirtual ってなんなの??
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
Java仮想マシンの命令セット
invokespecial #19; //Method MyObj.exe:()I
ニーモニック
【invokespecial】 インスタンスメソッドを呼び出す
オペランド
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
Java仮想マシンの命令セット
Java7では、Java仮想マシンの命令セットに
invokedynamic という命令セットが追加された
ワイルドだぜぇ
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
*MyObj this
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
メソッド実行時のJVM内部の動作
オペランドスタック ローカル変数
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
*MyObj
オペランドスタック ローカル変数
*MyObj
this
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
*MyObj
オペランドスタック ローカル変数
this
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
*MyObj
オペランドスタック ローカル変数
this
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
*MyObj
this
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
int
*MyObj
this
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
this
int
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
this
int
this
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
this
int
this
*MyObj
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
this
int
this
*MyObj
int
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
this
int
*MyObj’
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MyObj example(); 0: new #16; //class MyObj 3: dup 4: invokespecial #18; //Method MyObj."<init>":()V 7: astore_1 8: aload_1 9: invokevirtual #19; //Method MyObj.exe:()I 12: istore_2 13: aload_0 14: aload_1 15: iload_2 16: invokevirtual #23; //Method silly:(LMyObj;I)LMyObj; 19: areturn
オペランドスタック ローカル変数
*MyObj
this
int
*MyObj’
起動側フレームのスタックへとプッシュされる
メソッド実行時のJVM内部の動作
※オペランドスタック…Java仮想マシンの作業用領域※ローカル変数…各フレーム毎に保持される変数の配列※他に実行時コンスタントプールがある
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
または「やきに駆動」の資料
http://slidesha.re/se1Hun
詳しくは
Java仮想マシン仕様
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
InvokeDynamicの基本
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
簡単に言えば
型情報をもつ関数のポインタ
InvokeDynamicとは
JVM上で動作する動的言語のために追加
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
InvokeDynamicの基本
invokedynamic
bootstrapメソッド(初回時)
CallSite
MethodHandle 対象のメソッド実行
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
InvokeDynamicの基本
invokedynamic
bootstrapメソッド(初回時)
CallSite
MethodHandle 対象のメソッド実行
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
CallSite
MethodHandleの参照を保持する
ConstantCallSite MHは書き換えられない
MutableCallSite MHが書き換えられる
VolatileCallSite MHが書き換えられるVolatileである
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
InvokeDynamicの基本
invokedynamic
bootstrapメソッド(初回時)
CallSite
MethodHandle 対象のメソッド実行
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
MethodHandle
MHを合成したり、引数を部分適用したりして、対象のメソッドを呼び出す
MethodHandle#bindTo 第1引数のレシーバを固定
MethodHandles#insertArguments 引数を部分適用したMHを生成
MethodHandles#guardWithTest test, then, elseの3MHを合成して実行時に分岐するMH
MethodHandles#filterReturnValue 処理の戻り値に後処理を加えるMH
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
JVM上で動作する
動的言語
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
JVM上で動作する動的言語とは
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
JVM上で動作する動的言語とは
ここで グルービー のロゴ入れとけば
後でgdgd言われない!
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
コンパイラの恩恵を受けにくい
JVM上の動的言語の問題点
JITコンパイルは実行時に必要に応じて以下のような最適化を行う
・インライン展開・ループ展開・ロック解除・デッドコード削除・エスケープ解析
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
これらの最適化の処理を処理系がやっていた
DynamicInvokeがないとき
・いろいろ大変・その割に速度がでないetc..
12年4月30日月曜日
#shikadriven@能楽堂
COPYRIGHT 2012 PLUGRAM, inc.
JVMにおまかせ!
DynamicInvokeがあるとき
ただし、JVMに最適化されるように
・Javaのコードは極力入れない ・MHの再検索を極力減らす
などといったことに注意する
12年4月30日月曜日
まとめ
・呼び出すメソッドを動的に切り替えられる
InvokeDynamicを使うと...
・呼び出すメソッドを独自のルールで検索し実行できる
・JITコンパイルに最適化される
12年4月30日月曜日
ありがとうございました!
12年4月30日月曜日