ストックJDKでのGraalVM JavaScriptの実行

GraalVM JavaScriptは、GraalVMの一部として、またはGraalVMでビルドされた埋込みシナリオでの実行に最適化されています。これにより、最適化コンパイラとしてGraalVMコンパイラを使用し、場合によってはネイティブ・イメージを使用してエンジンをネイティブ・バイナリに事前にコンパイルすることで、可能な最善のパフォーマンスが保証されます。

GraalVM JavaScriptはJavaアプリケーションであるため、OpenJDKなどのストックJava VMで実行できます。GraalVMコンパイラを使用しないで実行すると、JavaScriptのパフォーマンスは大幅に低下します。ストックJVMで使用可能なJITコンパイラは、GraalVM JavaScriptコードベースを実行およびJITコンパイルできますが、可能な最大限のパフォーマンスを引き出すように最適化することはできません。このドキュメントでは、ストックJava VMでGraalVM JavaScriptを実行する方法について説明し、どのようにGraalVMコンパイラをJITコンパイラとして使用して可能な最善のパフォーマンスを保証できるかを示します。

Maven CentralでのGraalVM JavaScript

GraalVM JavaScriptはオープン・ソースであり、コミュニティによってMaven Centralリポジトリに定期的にプッシュされます。これは、パッケージorg.graalvm.jsとして見つけることができます。

GraalVMコンパイラを使用したJDK11 (またはそれ以降)のGraalVM JavaScriptのMavenプロジェクトの例が、graal-js-jdk11-maven-demoにあります。この例には、JavaScriptベンチマーク用のMavenプロジェクト(素数ジェネレータ)が含まれています。これにより、ユーザーは最適化コンパイラとしてGraalVMコンパイラを使用した場合と使用しない場合で、実行されたGraalVM JavaScriptのパフォーマンスを比較できます。GraalVMコンパイラを使用して実行すると、比較的大規模なJavaScriptコードベースの実行パフォーマンスが大幅に向上します。

基本的に、POMファイルの例では、JVMCIをアクティブ化して追加のJITコンパイラをインストールし、--module-pathおよび--upgrade-module-pathでそれを指定して、JITコンパイラがGraalVMコンパイラとなるように構成します。

JDK 11以降でのGraalVM JavaScript

前述のMavenの例は、JDK 11 (またはそれ以降)で起動するための望ましい方法です。Mavenを使用しないで、JARファイルをjavaコマンドに手動で指定できます。--upgrade-module-pathを使用すると、GraalVMコンパイラを使用してGraalVM JavaScriptが実行され、最高のパフォーマンスが保証されます。GraalVM JARファイルはMavenのorg.graalvmから、ICU4JライブラリはMavenのorg.ibm.icuからダウンロードできます。

LinuxおよびMacOS

JARS=/path/to/JARs
JDK=/path/to/JDK
$JDK/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler --module-path=$JARS/graal-sdk-22.2.0.jar:$JARS/truffle-api-22.2.0.jar --upgrade-module-path=$JARS/compiler-22.2.0.jar:$JARS/compiler-management-22.2.0.jar -cp $JARS/launcher-common-22.2.0.jar:$JARS/js-launcher-22.2.0.jar:$JARS/js-22.2.0.jar:$JARS/truffle-api-22.2.0.jar:$JARS/graal-sdk-22.2.0.jar:$JARS/js-scriptengine-22.2.0.jar:$JARS/regex-22.2.0.jar:$JARS/icu4j-71.1.jar com.oracle.truffle.js.shell.JSLauncher

Windows - Linux/MacOSコマンドに似ていますが、Windowのシェルの構文に合うように変更されています:

set JARs=c:\path\to\jars
set JDK=c:\path\to\jdk
%JDK%\bin\java -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler --module-path=%JARS%\graal-sdk-22.2.0.jar;%JARS%\truffle-api-22.2.0.jar --upgrade-module-path=%JARS%\compiler-22.2.0.jar;%JARS%\compiler-management-22.2.0.jar -cp %JARS%\launcher-common-22.2.0.jar;%JARS%\js-launcher-22.2.0.jar;%JARS%\js-22.2.0.jar;%JARS%\truffle-api-22.2.0.jar;%JARS%\graal-sdk-22.2.0.jar;%JARS%\js-scriptengine-22.2.0.jar;%JARS%\regex-22.2.0.jar;%JARS\icu4j-71.1.jar com.oracle.truffle.js.shell.JSLauncher

かわりにJavaアプリケーションを起動し、GraalVM SDKのContext (推奨)またはScriptEngine (サポートされていますが非推奨)を介してGraalVM JavaScriptを起動するには、launcher-common-*.jarおよびjs-launcher-*.jarを省略できます。

ScriptEngine JSR 223

js-scriptengine.jarがクラスパスに含まれている場合は、ScriptEngineを介してGraalVM JavaScriptを起動できます。このエンジンは、Graal.jsなど、複数の異なる名前で登録されています。Nashornエンジンもその名前で使用できることがあります(JDKで使用可能な場合)。

ScriptEngineからGraalVM JavaScriptを起動するには、次のコードを使用できます:

new ScriptEngineManager().getEngineByName("graal.js");

使用可能なすべてのエンジンをリストするには:

List<ScriptEngineFactory> engines = (new ScriptEngineManager()).getEngineFactories();
for (ScriptEngineFactory f: engines) {
    System.out.println(f.getLanguageName()+" "+f.getEngineName()+" "+f.getNames().toString());
}

設定の検査 - GraalVMコンパイラがJITコンパイラとして使用されるか

--engine.TraceCompilationフラグは、JavaScriptメソッドがGraalVMコンパイラによってコンパイルされるたびにデバッグ出力を有効にします。実行時間が十分に長いJavaScriptソース・コードによってコンパイルがトリガーされ、ログ出力が行われます:

> function add(a,b) { return a+b; }; for (var i=0;i<1000*1000;i++) { add(i,i); }
[truffle] opt done         add <opt> <split-c0875dd>                                   |ASTSize       7/    7 |Time    99(  90+9   )ms |DirectCallNodes I    0/D    0 |GraalNodes    22/   71 |CodeSize          274 |CodeAddress 0x7f76e4c1fe10 |Source    <shell>:1:1