quarta-feira, 2 de setembro de 2009

Basico de bytecode

Princípios:
Source File =
arquivo.java
Class File =
arquivo.class


Compilação:

Todo Source File gera um Class File quando compilado, ou seja Todo arquivo.java Compilado será um arquivo.class

- Cada Class File Contem Instruções, cada instrução possue um opcode de 1 byte (por isso bytecode) e cada opcode possui 1 mnemônico distinto.


Exemplo:

public class MinhaClasse{



}

Compilando esse Source File teremos um Class File.

Como ver os bytecodes de um Class File?
javap -c IdentificadoDoClassFile


Como fazer isso nesse Source File?
javap -c MinhaClasse Vamos obter:
public class MinhaClasse extends java.lang.Object{
public MinhaClasse();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return

}

Um exemplo de opcode é:
aload_0 e o Mnemônico dele é: 0x9

Qual a relação Processo main?

Toda vez que você tem um processo(para ter um processo é necessário o método main), Você tem uma thread, quando você tem uma thread você tem uma STACK, quando você tem uma Stack em um processo o Frame(Método) que vai ser executado é ou main ou um outro que não falaremos agora, Lembrando que isso é para Processos via linha de COMANDO:

Vamos ao exemplo:

public class MinhaClasse{

public static void main(String[] array){

}
}

Quando você executar o processo acontecerá isso:



Clique na imagem para ampliar



Mais oque é um frame?
Toda vez que um método é invocado ele vira um Frame na sua STACK.

Quem invoca o método main?
A própria Instância da JVM operando sobre a Stack



Oque eu tenho dentro da STACK?
- Local Variable = Variaveis Locais ao Frame(ao método)
- Operand Stack = Onde você empurra e relaciona valores, Normalmente em java trabalhamos aqui,também é usada para receber retornos de métodos e para preparar parametros para passar para argumentos.Os valores quando empurrados na Operand Stack ja tem o valor do tipo da variavel(ja tem um espaço daquele tamanho esperando aquele tamanho).
- Referência a Constant Pool = Todo Class file tem uma tabela chamada Constant Pool que é Mapeada para a arquitetura da JVM para a Runtime Constant Pool, que futuramente será feito Dynamic Linking para a real construção da HEAP(isso não importa agora), é o indice 0 da local Variable que é uma Referência a Constant Pool do Class File.

Então vamos desenhar:


Clique na imagem para ampliar
Qual a relação disso com bytecode?
A agora vamos la, essas áreas de memoria são usadas como pilhas...Empurando e retirando valores:


Temos aqui um Source File, Por causa do método main podemos ter um processo via linha de comando

public class MinhaClasse{


public static void main(String[] array){
int x = 3;
int y = 2;
int u = x + y;

}

}

O Class File desse Source:

Compiled from "MinhaClasse.java"
public class MinhaClasse extends java.lang.Object{
public MinhaClasse();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."
":()V
4: return

public static void main(java.lang.String[]);
Code:
0: iconst_3
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: return

}




Vamos por instruções:
public static void main(String[] array){

Estamos assim:

Clique na imagem para ampliar
Para abreviar usarei só Local Variable e Operand Stack e os bytecodes agora:

Agora estamos na instrução:
int x = 3;
int y = 2;
int u = x + y;

e em bytecodes:
0: iconst_3
1: istore_1
2: iconst_2
3: istore_2
4: iload_1
5: iload_2
6: iadd
7: istore_3
8: return
Ou seja dentro do Frame de main

Nesse site explica oque faz os bytecodes:
http://www.brics.dk/~mis/dOvs/jvmspec/ref-Java.html

0: iconst_3 = Empura 3 na Operand Stack

Desenhando:


Clique na imagem para ampliar

Lembrado que o 0(zero) da Local variable é a referência a Constant Pool, simplesmente ja esta la, não se importe com ele. Ele também é conhecido como this.


1: istore_1 = Armazena o valor que estiver no Topo da Operand Stack no index 1 da Local Variable


Clique na imagem para ampliar

2: iconst_2 = Empura 2 na Operand Stack

Clique na imagem para ampliar

3: istore_2 = Armazena o valor que estiver no Topo da Operand Stack no index 2 da Local Variable

Clique na imagem para ampliar
4: iload_1 = Carrega o inteiro que estiver no index 1 da Local Variable(Lembrando que java trabalha com cópias de valores(O valor é COPIADO))

Clique na imagem para ampliar
5: iload_2 = Carrega o inteiro que estiver no index 2 da Local Variable(Lembrando que java trabalha com cópias de valores(O valor é COPIADO))

Clique na imagem para ampliar
6: iadd = Pega os 2 primeiros valores do topo da Operand Stack e soma eles

Clique na imagem para ampliar

7: istore_3 = Pega o inteiro que estiver no topo da Operand Stack e armazena no index 3 da Local Variable

Clique na imagem para ampliar


Como não há mais nenhuma instrução, termina-se o processo e perdeu-se os valores.

Isso é o bem básico sobre tudo, porem acredito que desenhando tudo fica fácil.
Bom é isso
CYA DUDES!!



2 comentários:

  1. Muito bom seu trabalho parabens ! como nao vi email , gostaria que voce se possivel, me add no msn : arnaldo.net@hotmail.com

    ResponderExcluir