does-the-jvm-prevent-tail-call-optimizations の2年後、 prototypeimplementation および [〜#〜] mlvm [〜#〜] は、しばらくの間「proto 80%」として機能をリストしました。
Sun/Oracle側からテールコールのサポートに積極的な関心はありませんか、それとも単にテールコールが「[...] すべての機能優先リスト [...] " JVM Language Summit で述べたように?
誰かがMLVMビルドをテストし、それがうまく機能しているという印象を共有することができたら(もしあれば)本当に興味があります。
更新:Avian 問題なく適切なテールコールをサポートします。
診断Javaコード:パフォーマンスの改善Javaコード (- alt )は、JVMの理由を説明しています末尾呼び出しの最適化はサポートしていません。
しかし、末尾再帰関数を単純なループに自動的に変換する方法はよく知られていますが、Javaの仕様では、この変換を行う必要はありません。一般に、オブジェクト指向言語で変換を静的に行うことはできず、代わりに末尾再帰関数から単純なループへの変換をJITコンパイラーで動的に行う必要があります。
次に、Java変換しないコードの例を示します。
そのため、リスト3の例が示すように、静的コンパイラーが言語のセマンティクスを維持しながら、Javaコードで末尾再帰の変換を実行することを期待することはできません。代わりに、 JIT:JVMに応じて、JITはこれを行う場合と行わない場合があります。
次に、JITがこれを行うかどうかを判断するために使用できるテストを提供します。
当然、これはIBMの論文であるため、プラグが含まれています。
このプログラムをいくつかのJava SDKで実行しましたが、結果は驚くべきものでした。バージョン1.3のSunのHotspot JVMで実行すると、Hotspotは変換を実行しません。私のマシンでは1秒以内にスタックスペースが使い果たされますが、IBMのバージョン1.3のJVMは問題なく動作しており、この方法でコードを変換することを示しています。
Java)でTCOを実装していない(かつ難しいと見なされている)理由の1つは、JVMのパーミッションモデルがスタックに依存しているため、テールコールがセキュリティの側面を処理します。
これはClementsとFelleisen [1] [2]によって障害にならないことが示されたと信じており、質問で言及されたMLVMパッチもそれを扱っていると確信しています。
これはあなたの質問に答えないことを理解しています。興味深い情報を追加するだけです。
おそらくこれを既に知っているかもしれませんが、Java言語は実際にスタックトレースをプログラマに公開するので、機能は見かけほど簡単ではありません。
次のプログラムを検討してください。
public class Test {
public static String f() {
String s = Math.random() > .5 ? f() : g();
return s;
}
public static String g() {
if (Math.random() > .9) {
StackTraceElement[] ste = new Throwable().getStackTrace();
return ste[ste.length / 2].getMethodName();
}
return f();
}
public static void main(String[] args) {
System.out.println(f());
}
}
これには「テールコール」がありますが、最適化されていない場合があります。 (それがis最適化されている場合、プログラムのセマンティクスはそれに依存しているため、呼び出しスタック全体のブックキーピングが必要です。)
基本的に、これは、下位互換性を維持しながらこれをサポートすることが難しいことを意味します。