Java Virtual Machine - Otimizações JIT

Neste capítulo, aprenderemos sobre otimizações JIT.

Método Inlining

Nessa técnica de otimização, o compilador decide substituir suas chamadas de função pelo corpo da função. Abaixo está um exemplo para o mesmo -

int sum3;

static int add(int a, int b) {
   return a + b;
}

public static void main(String…args) {
   sum3 = add(5,7) + add(4,2);
}

//after method inlining
public static void main(String…args) {
   sum3 = 5+ 7 + 4 + 2;
}

Usando essa técnica, o compilador salva a máquina da sobrecarga de fazer qualquer chamada de função (ela requer o envio e o envio de parâmetros para a pilha). Assim, o código gerado é executado mais rápido.

O método inlining só pode ser feito para funções não virtuais (funções que não são substituídas). Considere o que aconteceria se o método 'add' fosse substituído em uma subclasse e o tipo de objeto que contém o método não fosse conhecido até o tempo de execução. Nesse caso, o compilador não saberia qual método embutir. Mas se o método foi marcado como 'final', então o compilador saberia facilmente que ele pode ser embutido porque não pode ser substituído por nenhuma subclasse. Observe que não é de todo garantido que um método final seria sempre in-lined.

Eliminação de código inatingível e morto

Código inacessível é o código que não pode ser alcançado por nenhum fluxo de execução possível. Devemos considerar o seguinte exemplo -

void foo() {
   if (a) return;
   else return;
   foobar(a,b); //unreachable code, compile time error
}

Código morto também é código inalcançável, mas o compilador expõe um erro neste caso. Em vez disso, apenas recebemos um aviso. Cada bloco de código, como construtores, funções, try, catch, if, while, etc., tem suas próprias regras para código inacessível definidas no JLS (Java Language Specification).

Dobramento Constante

Para entender o conceito de dobra constante, veja o exemplo abaixo.

final int num = 5;
int b = num * 6; //compile-time constant, num never changes
//compiler would assign b a value of 30.