Por que a JVM ainda não suporta otimização de chamada?

Dois anos após as otimizações do call-the-jvm-prevent-tail-call , parece haver uma implementação de protótipo e o MLVM listou o recurso como “proto 80%” por algum tempo.

Não existe nenhum interesse ativo do lado da Sun / Oracle em apoiar as chamadas finais ou é apenas que as chamadas finais estão “[…] destinadas a ficar em segundo lugar em todas as listas de […] prioridades de resources “, como mencionado na JVM? Cimeira da Linguagem ?

Eu ficaria realmente interessado se alguém testasse uma compilation de MLVM e pudesse compartilhar algumas impressões de como ela funciona (se é que funciona).

Atualização: Observe que algumas VMs, como a Avian, aceitam chamadas de retorno adequadas sem problemas.

Diagnosticando o Código Java: Melhorando o Desempenho do seu Código Java ( alt ) explica porque a JVM não suporta otimização de chamada.

Mas embora seja bem conhecido como transformar automaticamente uma function recursiva de cauda em um loop simples, a especificação Java não exige que essa transformação seja feita. Presumivelmente, uma razão pela qual não é um requisito é que, em geral, a transformação não pode ser feita estaticamente em uma linguagem orientada a objects. Em vez disso, a transformação da function recursiva da cauda em loop simples deve ser feita dinamicamente por um compilador JIT.

Em seguida, ele fornece um exemplo de código Java que não será transformado.

Portanto, como mostra o exemplo na Listagem 3, não podemos esperar que os compiladores estáticos executem a transformação da recursion de cauda no código Java enquanto preservam a semântica da linguagem. Em vez disso, devemos confiar na compilation dinâmica pelo JIT. Dependendo da JVM, o JIT pode ou não fazer isso.

Em seguida, ele dá um teste que você pode usar para descobrir se o seu JIT faz isso.

Naturalmente, como este é um papel da IBM, ele inclui um plug:

Eu corri este programa com um par de Java SDKs, e os resultados foram surpreendentes. A execução na JVM do Hotspot da Sun para a versão 1.3 revela que o Hotspot não realiza a transformação. Nas configurações padrão, o espaço da pilha está esgotado em menos de um segundo na minha máquina. Por outro lado, a JVM da IBM para a versão 1.3 passa sem problemas, indicando que ela transforma o código dessa maneira.

Uma razão que vi no passado para não implementar o TCO (e ser visto como difícil) em Java é que o modelo de permissão na JVM é sensível a pilha e, portanto, as chamadas finais devem lidar com os aspectos de segurança.

Eu acredito que isso foi mostrado para não ser um obstáculo por Clements e Felleisen [1] [2] e eu tenho certeza que o patch MLVM mencionado na questão lida com isso também.

Eu percebo que isso não responde à sua pergunta; apenas adicionando informações interessantes.

  1. http://www.ccs.neu.edu/scheme/pubs/esop2003-cf.pdf
  2. http://www.ccs.neu.edu/scheme/pubs/cf-toplas04.pdf

Talvez você já saiba disso, mas o recurso não é tão trivial quanto parece, já que a linguagem Java expõe o rastreamento de pilha ao programador.

Considere o seguinte programa:

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

Mesmo que isso tenha um “tail-call”, pode não ser otimizado. (Se for otimizado, ainda requer a manutenção de todos os registros de chamadas, já que a semântica do programa depende dele.)

Basicamente, isso significa que é difícil suportar isso enquanto ainda é compatível com versões anteriores.

Java é a linguagem menos funcional que você poderia imaginar (bem, OK, talvez não !), Mas isso seria uma grande vantagem para as linguagens da JVM, como o Scala , que são.

Minhas observações são de que fazer da JVM uma plataforma para outras linguagens nunca pareceu estar no topo da lista de prioridades da Sun e, suponho, agora para a Oracle.