JVM / CLRはJITコンパイル済みネイティブコードをどのように実行しますか?コードインジェクションによるものですか、それとも実行可能メモリへのコードのコピーによるものですか?動的なコード実行を可能にするシステムコールとは何ですか?
3 に答える
CACAO VM (研究用 JIT 専用 JVM)でそれを行う方法を説明できます。まず、メソッドのマシン コードが、ヒープに割り当てられたメモリ ブロックに生成されます。コンパイル後、最終的なコード長が判明mmap
し、PROT_EXEC
フラグを使用して実行可能メモリのチャンクが割り当てられます (関連する CACAO コードはこちら)。次に、マシンコードが mmaped 領域にコピーされます。その後、多くのアーキテクチャでは、マシン固有のキャッシュ フラッシュ メカニズムが必要になります。例として、PowerPC 64 のキャッシュ フラッシュ機能を見てください。特に、i386 と x86_64 では何もする必要はありません。このステップの後、プロセッサは新しく生成されたコードを実行する準備が整います。または、すでに割り当てられているメモリページを実行可能としてマークすることができますmprotect
. mmap
/mprotect
は Unix の機能であることに注意してください。
共通言語ランタイムには、ネイティブコードまたはJITマネージコードへのネイティブスタブを指すエントリを持つ各タイプのメソッドテーブルがあり、作成されたばかりのネイティブコードへのポインターでメソッドテーブルを修正します。
MSDNのMethodDescセクションに詳細な説明があります
Dave Notarioによるこのブログエントリでは、CLRJITコンパイラがどのように機能するかを説明しています。
Java がどのようにそれを行うのかは具体的にわかりませんが、一般的には「トラップ」オペコードをインタープリターの命令ストリームに挿入します。JVM 仕様には、この目的に合わせて作成されたように見える2 つのオペコードがあります。
確実に知りたい場合は、ソースよりも良い答えはありません: http://download.java.net/jdk6/source/