ストック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コンパイラとなるように構成します。

Mavenを使用しないGraalVM JavaScript - GraalVMのJARファイル

Mavenを使用しないために、GraalVMリリースのJARファイルも使用できます。GraalVMは、Enterprise EditionおよびCommunity Editionとして入手できます。両方のエディションのファイルを使用できます。

関連するファイルは次のとおりです:

ここに表示されているファイルは、JDK8ビルド用です。JDK11以降のビルドでは、*.jarファイルは別のディレクトリにあります。

JDK 8でのGraalVM JavaScript

次のコマンドラインは、JDK 8でGraalVM JavaScriptを実行して、JavaScriptコンソールを起動します。このバリアントには最適化コンパイラとしてGraalVMコンパイラが含まれていないため、GraalVM JavaScriptのパフォーマンスは最適ではないことに注意してください。この点を改善する方法は、次のJDK 11の例を参照してください。

Linuxの場合

GRAALVM=/path/to/GraalVM
JDK8=/path/to/jdk8
$JDK8/bin/java -cp $GRAALVM/jre/lib/graalvm/launcher-common.jar:$GRAALVM/jre/lib/graalvm/graaljs-launcher.jar:$GRAALVM/jre/languages/js/graaljs.jar:$GRAALVM/jre/lib/truffle/truffle-api.jar:$GRAALVM/jre/lib/boot/graal-sdk.jar:$GRAALVM/jre/lib/boot/graaljs-scriptengine.jar:$GRAALVM/jre/languages/regex/tregex.jar:$GRAALVM/jre/languages/js/icu4j.jar com.oracle.truffle.js.shell.JSLauncher

MacOSの場合 - Linuxコマンドと同じですが、GraalVMへのパスにContents/Homeを追加する必要があります:

GRAALVM=/path/to/graalvm/Contents/Home

Windowsの場合 - GraalVM JavaScriptでは、Windowsの予備のサポートが提供されます:

set GRAALVM=c:\path\to\graalvm
%GRAALVM%\bin\java -cp %GRAALVM%\jre\lib\graalvm\launcher-common.jar;%GRAALVM%\jre\lib\graalvm\graaljs-launcher.jar;%GRAALVM%\jre\languages\js\graaljs.jar;%GRAALVM%\jre\lib\truffle\truffle-api.jar;%GRAALVM%\jre\lib\boot\graal-sdk.jar;%GRAALVM%\jre\lib\boot\graaljs-scriptengine.jar;%GRAALVM%\jre\languages\regex\tregex.jar;%GRAALVM%\jre\languages\js\icu4j.jar com.oracle.truffle.js.shell.JSLauncher

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

ScriptEngine JSR 223

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

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());
}

このコードがMyJavaApp.javaからコールされてクラス・ファイルに適切にコンパイルされると、次のように実行できます:

GRAALVM=/path/to/GraalVM
JDK8=/path/to/jdk8
$JDK8/bin/java -cp $GRAALVM/jre/languages/js/graaljs.jar:$GRAALVM/jre/lib/truffle/truffle-api.jar:$GRAALVM/jre/lib/boot/graal-sdk.jar:$GRAALVM/jre/lib/boot/graaljs-scriptengine.jar:$GRAALVM/jre/languages/regex/tregex.jar:$GRAALVM/jre/languages/js/icu4j.jar:. MyJavaApp

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からダウンロードできます。

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

設定の検査 - 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