GraalVMとネイティブ・コードの相互作用

GraalVM LLVMランタイムにより、ユーザーは、一般的にネイティブ・コードに直接コンパイルされる言語で記述されたコードを実行できます。通常、これらの言語では、管理対象ランタイムまたはVMの実行は必要ありません。そのため、特にコードが特定の低レベル機能を使用している場合、GraalVMの管理対象ランタイムとのこのコードの相互作用を検討する際は、特別な注意が必要です。

低レベルのシステム・コールへのアクセス制限

メモリー・レイアウト

GraalVMで実行されているプロセスのメモリーとスタックのレイアウトは、直接のネイティブ実行とは異なります。特に、グローバル、スタック変数などの相対位置などに関する前提はありません。

スタックの移動は、GraalVM APIを使用した場合にのみ可能です。コードとデータの間には厳密な分離があります。自己変更コードは動作しません。コードへのポインタに対する読取り、書込みおよびポインタ演算はサポートされていません。

ネイティブ・モードでのシステム・ライブラリとの相互作用

ネイティブ実行モード(デフォルト・モード)で、GraalVM LLVMランタイムで実行されているコードは、実際のネイティブ・ライブラリ(システム・ライブラリなど)へのコールを実行できます。これらのコールは、JavaのJNIコールと同様に動作し、管理された実行環境を一時的に終了します。

これらのライブラリで実行されるコードはGraalVMの制御下にはないため、このコードは基本的に何でも行うことができます。特に、マルチテキスト分離は適用されず、仮想ファイルシステムのようなGraalVM APIはバイパスされます。

これは、特に標準のCライブラリのほとんどに適用されます。

管理対象実行モード

管理対象モード(--LLVM.managedオプションで有効化)は特別な実行モードであり、LLVMランタイムは他のすべてのGraalVMサポート対象言語と同様に管理モードで実行されます。

ノート: 管理対象モードはOracle GraalVMでのみ使用できます。

このモードでは、設計上、ネイティブ・コードのコールおよびネイティブ・メモリーへのアクセスは許可されません。すべてのメモリーはガベージ・コレクタによって管理され、実行する必要があるすべてのコードをビットコードにコンパイルする必要があります。

ポインタ演算は、C標準で許可されている範囲でのみ可能です。特に、オーバーフローは防止されており、範囲外アクセスを介して異なる割当てにアクセスすることはできません。このような無効なアクセスはすべて、未定義の動作ではなく、実行時例外になります。

管理対象モードでは、GraalVMは仮想Linux/AMD64オペレーティング・システムをシミュレートし、C/C++標準ライブラリとしてmusl libcおよびlibc++を使用します。すべてのコードをそのシステムにコンパイルする必要があり、これを使用して、GraalVMでサポートされている任意のアーキテクチャまたはオペレーティング・システムで実行できます。Syscallは仮想化され、適切なGraalVM APIを介してルーティングされます。

ネイティブ・コードと管理対象言語間のポリグロット相互作用

LLVM言語(C/C++など)と管理対象言語(JavaScript、Python、Rubyなど)のポリグロット相互運用性を使用する場合は、手動メモリー管理に注意する必要があります。この項は、実行のネイティブ・モード(デフォルト)にのみ適用されます。管理対象モード(--llvm.managedオプションで有効化され、Oracle GraalVMでのみ使用可能)では、LLVMランタイム自体が管理対象言語のように動作し、ポリグロット相互作用は他の管理対象言語間と同じです。