Javaバイトコード命令セットの概要

6232 ワード

Java仮想マシン命令は、1バイト長の、ある特定の意味を表すオペランドコード(Opcode)と、その後の0から複数のオペランドパラメータを表すオペランドから構成される.仮想マシンの多くの命令にはオペランドは含まれておらず、オペランドコードは1つしかありません.例外を無視すると、JVMインタプリタはコードとして使用して有効に動作します.
do{
        PC      PC           
    if(     )      ;
               ;
}while(       )
   
オペランドの数および長さは、オペランドコードによって異なり、オペランドの長さが1バイトを超えると、Big-endian順に格納され(上位バイトコード)、その値は(byte 1<<8)|byte 2であるべきである.
    バイトコード命令ストリームは単一バイト整列であり、「tableswitch」と「lookupswitch」の2つの命令のみが例外であり、それらの操作数は比較的特殊であり、4バイトを限界として区分されており、対応する空きスペースを残して整列を実現する必要がある.
    Java仮想マシンのオペレーティングコードの長さを1バイトに制限し、コンパイル後のコードのパラメータ長の位置合わせを放棄するのは、JVMが一定の性能コストを払う可能性がある場合でも、短い洗練されたコンパイルコードを得るためです.オペレーティングコードは1バイトの長さしか持たないため、命令セットの数を制限し、データが整列していると仮定することはなく、データが1バイトを超えると、バイトから具体的なデータ構造を再構築せざるを得ず、いくつかの性能を損なうことを意味する.
データ型とJava仮想マシン    JVMのコマンドセットでは、ほとんどのコマンドには、その動作に対応するデータ型情報が含まれています.iload命令のように局所変数テーブルからint型のデータをオペランドスタックにロードし、floadはfloat型のデータをロードする.
    データ型に関連するバイトコード命令の大部分について、彼らの操作コードアシストは、iがintタイプを表し、lがlongを表し、sがshortを表し、bがbyteを表し、cがcharを表し、fがfloatを表し、dがdoubleを表し、aがreferenceを表すことを示す特殊な文字を持っている.いくつかの個別の命令は、必要に応じて、サポートされていないタイプをサポート可能なタイプに変換するために使用することができる.
ロードとストレージ命令    ロードおよびストレージ命令は、スタックフレームのローカル変数テーブルとオペランドスタックとの間からデータを往復伝送するために使用される.
    1)オペランドスタックにローカル変数をロードする命令は、iload,iload_,lload、lload_、float、fload_、dload、dload_,aload、aload_.
    2)オペランドスタックからローカル変数ラベルに数値を格納する命令:istore,istore_,lstore,lstore_,fstore,fstore_,dstore,dstore_,astore,astore_
    3)オペランドスタックに定数をロードする命令:bipush,sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_ml,iconst_,lconst_,fconst_,dconst_
    4)ローカル変数テーブルのアクセスインデックス命令:wide
    一部のカッコで終わる命令はiload_のような命令のセットを表します.iload_を表します0,iload_1等、これらの命令群はいずれも1つの操作数を有する汎用命令である.
えんざんめいれい    算術命令は、2つのオペランドスタックの値を特定の演算し、結果をオペランドスタックの上部に再格納するために使用されます.
    1)加算命令:iadd,ladd,fadd,dadd
    2)減算指令:isub,lsub,fsub,dsub
    3)乗算指令:imul,lmul,fmul,dmul
    4)除算指令:idiv,ldiv,fdiv,ddiv
    5)余剰指令を求める:irem,lrem,frem,drem
    6)取反指令:ineg,leng,fneg,dneg
    7)変位指令:ishl,ishr,iushr,lshl,lshr,lushr
    8)ビットまたは命令による:ior,lor
    9)按位与指令:iand,land
    10)按位异或指令:ixor,lxor
    11)局所変数自己増加指令:iinc
    12)比較指令:dcmpg,dcmppl,fcmpg,fcmpl,lcmp
    Java仮想マシンは、整数データがオーバーフローすることを明確に規定していないが、整数データの処理を規定した場合、除算と余剰命令のみ除算が0の場合、仮想マシンから異常が放出される.
ロードとストレージ命令
    ロードとストレージコマンドは、スタックフレームを通過するローカル変数テーブルとオペランドスタックとの間からデータを転送するために使用されます.
    1)オペランドスタックにローカル変数をロードする命令は、iload,iload_,lload、lload_、float、fload_、dload、dload_,aload、aload_.
    2)オペランドスタックからローカル変数ラベルに数値を格納する命令:istore,istore_,lstore,lstore_,fstore,fstore_,dstore,dstore_,astore,astore_
    3)オペランドスタックに定数をロードする命令:bipush,sipush,ldc,ldc_w,ldc2_w,aconst_null,iconst_ml,iconst_,lconst_,fconst_,dconst_
    4)ローカル変数テーブルのアクセスインデックス命令:wide
    一部のカッコで終わる命令はiload_のような命令のセットを表します.iload_を表します0,iload_1等、これらの命令群はいずれも1つの操作数を有する汎用命令である.
えんざんめいれい   
算術命令は、2つのオペランドスタックの値を特定の演算し、結果をオペランドスタックの上部に再格納するために使用されます.
    1)加算命令:iadd,ladd,fadd,dadd
    2)減算指令:isub,lsub,fsub,dsub
    3)乗算指令:imul,lmul,fmul,dmul
    4)除算指令:idiv,ldiv,fdiv,ddiv
    5)余剰指令を求める:irem,lrem,frem,drem
    6)取反指令:ineg,leng,fneg,dneg
    7)変位指令:ishl,ishr,iushr,lshl,lshr,lushr
    8)ビットまたは命令による:ior,lor
    9)按位与指令:iand,land
    10)按位异或指令:ixor,lxor
    11)局所変数自己増加指令:iinc
    12)比較指令:dcmpg,dcmppl,fcmpg,fcmpl,lcmp
    Java仮想マシンは、整数データがオーバーフローすることを明確に規定していないが、整数データの処理を規定した場合、除算と余剰命令のみ除算が0の場合、仮想マシンから異常が放出される.
タイプ変換命令    タイプ変換コマンドは、ユーザコードの明示的なタイプ変換操作を実現するために一般的に使用される2つのJava仮想マシンの数値タイプを相互に変換します.
    JVMはワイドタイプ変換(小範囲タイプから大範囲タイプへの変換)をサポートする:
    1)intタイプからlong,float,doubleタイプ
    2)longタイプからfloat,doubleタイプへ
    3)floatからdoubleタイプ
    狭花型変換指令:i 2 b,i 2 c,i 2 s,l 2 i,f 2 i,f 2 l,d 2 l,d 2 f、狭化型変換は変換結果に異なる正負号を生じさせ、異なる桁数で変換過程が数値的に精度を失う可能性がある.intまたはlongタイプが整数タイプTに変換する場合、
変換プロセスは、最下位のNバイトの予期せぬコンテンツのみを破棄する(NはタイプTのデータ型長である)
オブジェクトの作成と操作    クラスインスタンスと配列はオブジェクトですが、Java仮想マシンはクラスインスタンスと配列の作成と操作に異なるバイトコード命令を使用します.
    1)インスタンス作成命令:new
    2)配列を作成する命令:newarray,anewarray,multianewarray
    3)アクセスフィールド命令:getfield,putfield,getstatic,putstatic
    4)配列要素をオペランドスタック命令にロードする:baload,caload,saload,iaload,laload,faload,daload,aaload
    5)オペランドスタックの数値を配列要素に格納して実行する:bastore,castore,castore,sastore,iastore,fastore,dastore,aastore
    6)配列長指令を取る:arraylength
    7)検査インスタンスタイプ指令:instanceof,checkcast
オペランドスタック管理命令    直接操作オペランドスタックの指令:pop,pop 2,dup,dup 2,dup_x1,dup2_x1,dup_x2,dup2_x 2とswap
せいぎょてんいめいれい
    JVMに転送命令を制御する代わりに指定された命令から条件付きまたは無条件で次の命令からプログラムを実行させます.制御転送命令は次のとおりです.
    1)条件分岐:ifeq,iflt,ifle,ifne,ifgt,ifge,ifnull,ifnotnull,if_cmpeq,if_icmpne,if_icmlt,if_icmpgt等
    2)複合条件分岐:tableswitch,lookupswitch
    3)無条件分岐:goto,goto_w,jsr,jsr_w,ret
    JVMにはintとreferenceタイプの条件分岐比較操作を扱う専用命令セットがあり、エンティティ値がnullであるかどうかを明確に示すことができないようにnull値を検出する専用命令があります.booleanタイプとbyteタイプ、charタイプとshortタイプの条件分岐比較操作は、intタイプの比較命令で完了し、long、float、double条件分岐比較操作は、対応するタイプの比較演算命令によって、演算命令はオペランドスタックに整数値を返し、intタイプの条件比較操作を実行して分岐ジャンプ全体を完了します.各タイプの比較は最終的にintタイプの比較操作に変換されます.
メソッド呼び出しと戻り命令    invokevirtualコマンド:オブジェクトのインスタンスメソッドを呼び出し、オブジェクトの実際のタイプに応じて割り当てます(仮想マシン割り当て).
    invokeinterface命令:インタフェースメソッドを呼び出し、実行時にこのインタフェースメソッドを実現するオブジェクトを検索し、適切なメソッドを見つけて呼び出します.
    invokespecial:インスタンス初期化メソッド、プライベートメソッド、親メソッドなど、特殊な処理が必要なインスタンスメソッドを呼び出します.
    invokestatic:クラスメソッドの呼び出し(static)
    メソッド戻り命令は、ireturn(戻り値はboolean,byte,char,shortおよびint)、lreturn,freturn,drturnおよびareturnを含む戻り値のタイプに応じて区別され、voidメソッド、インスタンス初期化メソッド、クラスおよびインタフェースのクラス初期化iメソッドで使用される別のreturnが使用される.
同期    JVMはメソッドレベルの同期とメソッド内部の命令シーケンスの同期をサポートし、どちらもmoniterによって実現されます.
    メソッドレベルの同期は暗黙的であり、バイトコード命令によって制御する必要がなく、メソッド呼び出しおよび戻り動作で実現される.メソッド定数プールのメソッドラベル構造からの仮想マシンのACC_SYNCRONIZEDフラグは、同期方法であるか否かを区別する.メソッド呼び出しの場合、呼び出しコマンドはフラグが設定されているかどうかをチェックし、設定されている場合、実行スレッドはmoniterを持ち、メソッドを実行し、最後にメソッドが完了するとmoniterを解放します.
    synchronizedの意味をサポートするために、通常synchronizedブロックによって示される命令セットのシーケンスを同期します.JVM命令セットにはmonitorenterとmonitorexitがあります.
    構造化ロックとは、メソッド呼び出し中に各monitor終了が前のmonitorエントリと一致する場合を指す.JVMは次の2つの規則によって接合構造化ロックの成立を保証する(Tはスレッドを表し、Mはmonitorを表す).
    1)Tがメソッド実行時にMを持つ回数は、メソッド完了時にTが解放するMの回数と等しくなければならない
    2)TがMを持つ回数よりもTがMを解放する回数が多くなることはいつでもない