JVM- Máquina Virtual Java ©André Santos / Pablo Sampaio.
-
Upload
liliana-de-andrade-arantes -
Category
Documents
-
view
227 -
download
0
Transcript of JVM- Máquina Virtual Java ©André Santos / Pablo Sampaio.
JVM- Máquina Virtual Java
©André Santos / Pablo Sampaio
Estrutura da Apresentação
• Máquinas Virtuais• Introdução à JVM• Arquivo class• Tipos de Dados• Descritores de Tipos• Frames• Instruções• Compilando para a JVM• Referências
• Definições: – Particionamento de uma máquina: sistema
IBM VM/ESA para o IBM 370 (1965).– SO rodando sobre SO: Unix sobre Windows– Software que simula o comportamento de
uma máquina (diferente daquela na qual roda).• Emuladores
– Ambientes independentes de plataforma para linguagens de programação
Máquinas Virtuais
• O-Code machine para BCPL (1960’s)• P-Code machine para UCSD Pascal
(1970´s)• Smalltalk (1970´s)• Java Virtual Machine para Java
(1995)• Microsoft .NET: VB, C#, C++, ... (2001)
Máquinas Virtuais para LP´s
• Impacto na Performance– Linguagens Interpretadas: JavaScript,
Perl, etc.• Portabilidade e Segurança• 100x a 200x mais lentas que C
– Linguagens Baseadas em Bytecodes• Linguagens semi-compiladas• 10 a 20x mais lentas que C• JIT: ~5x mais lenta que C
Máquinas Virtuais para LP´s
• Engenho que executa um programa Java• Processador virtual:
– Possui seu próprio conjunto de instruções– Manipula diferentes áreas de memória
• Baseada em pilha de operandos• Responsável por gerenciar: memória
(garbage collector), erros, exceções, threads
JVM - Introdução
• Garante as seguintes características da linguagem Java:– Portabilidade– Eficiência (JIT)– Segurança
JVM - Introdução
• A JVM não “sabe” nada da linguagem Java. Ela entende apenas arquivos em um formato binário particular: arquivos class.
• Permite rodar outras linguagens desde que seja possível traduzi-las para arquivos class.– Haskell, Pascal, Ada etc.
• Instruções lembram as de processadores reais, mas são mais complexas (de mais alto nível).– Ex: Instruções para manipular objetos
JVM - Introdução
• Camadas de abstração:Programa em Java
JVMSistema Operacional
Hardware
Java Bytecode
JVM - Introdução
• Formato único independente de plataforma• Ênfase na compacidade• Representa de maneira precisa uma classe
ou interface• Guarda informações sobre: atributos,
métodos, permissões de acesso, herança.• Informações extras: nomes das variáveis
locais, linhas do código (Java), etc.
Arquivo class
• Constant Pool: armazena valores constantes referenciados pelas instruções. Exemplos:– Nomes e assinaturas de métodos e
atributos– Nomes de classes– Constantes numéricas– Strings constantes
• Constant Pool favorece a compacidade
Arquivo .class
Arquivo class
• Dividem-se em:– Primitivos– Referência
• Checagem de tipos deve ser feita em tempo de compilação (ou pelo Verifier)
• JVM não faz distinção entre valores de tipos diferentes.
• No entanto, oferece instruções específicas para cada tipo de dado.
Tipos de Dados
• Tipos numéricos:– Inteiros:
• byte: 8 bits com sinal• char: 16 bits sem sinal, representando
caracteres Unicode• short: 16 bits com sinal• int: 32 bits com sinal• long: 64 bits com sinal
– Ponto-flutuante:• float: 32 bits com sinal• double: 64 bits com sinal
Tipos Primitivos
• Tipo boolean:– Suporte limitado, não há instrução que opere
exclusivamente sobre esse tipo de dado– Em geral, é tratado com o tipo int da JVM– Valores: 0 (false) e 1 (true)
• Tipo returnAddress:– Seus valores são ponteiros para opcodes da JVM– Usado por algumas instruções da JVM– Único tipo que não tem correspondente em Java
Tipos Primitivos
• É o tipo usado para referenciar: arrays, classes e interfaces
• Seus valores são endereços para objetos criados dinamicamente
• O valor null representa uma referência inválida
Tipo Referência
Descritores de Tipos
• São strings usadas para descrever o tipo de um atributo ou método dentro de um arquivo class.– Exemplos: “[[I” significa int[][]
• São usados para definir a assinatura de métodos e atributos e também para acessá-los.
Descritores de Tipos
• descritor_simples: básico | array | classe• Tipos básicos:
– “Z”: boolean– “B”: byte– “I”: int– “F”: float– “J”: long– etc.
Descritores de Tipos
• Arrays: “[“ + <descritor_simples>– Ex.: “[[[Z” => boolean[][][]
• Classes: “L” + <nome_classe> + “;”– nome_classe: nome “completo” da
classe (informando o pacote a que ela pertence, usando barras “/” ao invés de ponto “.”)
– Ex.: “Ljava/lang/String;” => String
Descritores de Tipo
• Métodos: “(“ + <descritor_simples>* + “)” +
<descritor_simples>• Exemplo:
– Um método Java:long[] myMethod(int i, double d, Thread t)
– Descritor do método:(IDLjava/lang/Thread;)[J
• São estruturas que guardam informações específicas de uma chamada de método.
• São criados a cada chamada de método e destruídos quando a chamada termina.
• São sucessivamente empilhados na JVM Stack em chamadas aninhadas.
• Cada frame da JVM possui:– Uma pilha de operandos– Um array de variáveis (locais)– Referência para a runtime Constant Pool
Frames
• Array de variáveis locais– Posições de 4 bytes acessadas através de
seus índices– Valores byte, char, short, int, ... ocupam
uma única posição do array– Valores long e double ocupam duas
posições– Tem seu tamanho determinado em tempo
de compilação e informado no arquivo class
Frames
• Pilha de operandos– Estrutura FILO de onde as instruções buscam
seus operandos e para onde retornam resultados
– Vazia quando o frame é criado– Usada para preparar parâmetros para a
chamada a um método, bem como para retornar valores
– Tamanho determinado em tempo de compilação– long e double ocupam dois espaços
Frames
this
argu
mento
s
var.
locais
Pilha de Operandos
Ref. Constant Pool
0 <Class> “My Class”1 <String> “Hello World”2 <Integer> 1234567... ...
0 1 2 3 4 5
JVM Stack
Frame 1
Frame 2
Frame 3
Frame 4
Frame 5
Frames
Instruções
• O conjunto de instruções da JVM não é ortogonal, ou seja, instruções disponíveis para um tipo podem não possuir instrução análoga para outro tipo.– O tipo int é o que apresenta melhor suporte na
JVM: 23 instruções– O tipo boolean apresenta o pior suporte: 0
instruções• Alguns tipos são operados como int:
– char, boolean: estendidos (para 32 bits) com zero
– byte, short: estendidos com o sinal
Instruções
• Instruções com opcodes de apenas 1 byte.
• Algumas instruções vêm acompanhadas de um ou mais operandos.
• A maioria das instruções da JVM opera apenas sobre um tipo específico.
• A maioria das instruções tem representado no seu mnemônico o tipo sobre o qual ela opera.
Instruções
• Uma letra para representar cada tipo:– i : operações sobre int– l : operações sobre long– s : operações sobre short– b : operações sobre byte– c : para char– f : para float– d : para double– a : para o tipo referência (classes, arrays,
interfaces)
Instruções
• Instruções de load/store:– Para carregar uma variável local na pilha
de operandos: iload, lload, dload, aload, etc.
– Para armazenar uma valor da pillha de operandos em uma variável local: istore, lstore, fstore, dstore, astore, etc.
– Colocar uma constante na pilha de operandos: bipush, sipush, ldc, aconst_null, etc.
Instruções
• Instruções aritméticas:– Soma: iadd, ladd, fadd, dadd.– Multiplicação: imul, lmul, fmul, dmul.– Negação: ineg, lneg, fneg, dneg.– Shift: ishl, ishr, lshl, lshr, etc.– AND bit-a-bit: iand, land.– Comparação: dcmpg, dcmpl, fcmpg, lcmp, etc.
• Retornam –1 (menor), 0 (igual) ou +1 (maior)– Incrementa variável local (sem colocar na pilha):
iinc.– etc.
Instruções
...3 iload_2
4 bipush 10
6 iadd
7 istore_3
...23
31
23
5
4
3
2
1
0
23
33
...3 iload_2
4 bipush 10
6 iadd
7 istore_3
...
...3 iload_2
4 bipush 10
6 iadd
7 istore_3
...
...3 iload_2
4 bipush 10
6 iadd
7 istore_3
...
...3 iload_2
4 bipush 10
6 iadd
7 istore_3
...23
10
33
...3 iload_2
4 bipush 10
6 iadd
7 istore_3
...
Instruções
• Conversões de tipo:– A primeira letra é o tipo origem, a última é o tipo
destino.– O número 2 tem o sentido de “to” (para).– A JVM suporta diretamente as seguinte
conversões de extensão (sem perdas significativas):
• int => long => float => double• i2l, i2f, l2f, f2d.
– As outras conversões suportadas podem resultar em perdas significativas do valor: i2b, i2c, l2i, ...
Instruções
• Instruções para criação e manipulação de objetos:– Criação de objetos: new, newarray,
etc.– Acessar atributos: getfield, putfield,
etc.– Acessar uma posição do array: baload,
caload, bastore, castore, etc.– Tamanho do array: arraylength
Instruções
• Checar propriedades dos objetos: instanceof, checkcast.
• Instruções para manipulação da pilha e do array de variáveis: pop, pop2, dup, dup2, swap, wide, etc.
Instruções
• Instruções de controle (desvios):– Desvios incondicionais: goto, goto_w, etc.– Desvios condicionais: ifeq, iflt, ifle, ifnull, etc.
• Desvios condicionais sobre o tipo int realizam a comparação automaticamente: if_icmplt, if_icmpeq, if_icmpg, etc.
• Desvios condicionais sobre outros tipos precisam ser precedidos por uma instrução de comparação:
dcmpgifeq loop
– Switch: tableswitch, lookupswitch
Instruções
...5 fcmpg
6 ifeq 11
9 aconst_null
10 astore_2
11 fload_0
...
5
4
3
2
1
0
1.0
5.43
1.0
1.00
...5 fcmpg
6 ifeq 11
9 aconst_null
10 astore_2
11 fload_0
...
...5 fcmpg
6 ifeq 11
9 aconst_null
10 astore_2
11 fload_0
...
...5 fcmpg
6 ifeq 11
9 aconst_null
10 astore_2
11 fload_0
...
...5 fcmpg
6 ifeq 11
9 aconst_null
10 astore_2
11 fload_0
...5.43
...5 fcmpg
6 ifeq 11
9 aconst_null
10 astore_2
11 fload_0
...
Instruções
• Chamada e retorno de métodos:– Chamada: invokevirtual,
invokespecial, invokestatic.– Retorno: lreturn, freturn, ireturn.– Ao chamar um método, os parâmetros
devem ser colocados (na ordem da declaração) na pilha. Quando a execução termina, o valor de retorno, se houver, é colocado no topo da pilha do frame “pai”.
Compilando para a JVM
• Arquivo “HelloWorld.java”:
public class HelloWorld { public static void main(String args[]) { System.out.println(“Hello World!”);
}}
• javac HelloWorld.java– Gera o arquivo HelloWorld.class
Compilando para a JVM
• A ferramenta javap, distribuída junto com o JDK da Sun, permite decompilar:> javap –c HelloWorld.class
Compiled from HelloWorld.javapublic class HelloWorld extends java.lang.Object {
public static void main(java.lang.String[]);}Method void main(java.lang.String[]) 0 getstatic #2 <Field java.io.PrintStream out> 3 ldc #3 <String "Hello World!"> 5 invokevirtual #4 <Method void
println(java.lang.String)> 8 return
Compilando para a JVM
• O código gerado pelo javap não pode ser alterado e recompilado.
• Para compilar uma arquivo com código assembler JVM é necessário usar alguma biblioteca. – Exemplos: Jas, Jasmin, Kawa, etc.
Jasmin
• Java Assembler Interface.• Compilador de assembly JVM para
arquivos class. • Recebe um arquivo texto como entrada.• A sintaxe do arquivo é parecida com a
dos arquivos gerados com o javap.• java jasmin.Main <arquivo_fonte>
Jasmin – Exemplos
• Exemplo de chamada de método– Código Java original
int add12and13() {return addTwo(12, 13);
}
Jasmin – Exemplos
• Exemplo de chamada de método– Código Jasmin:
.method add12and13()Iaload_0 //coloca variável zero na pilha (this)bipush 12 //coloca constante 12 na pilhabipush 13 //coloca constante 13 na pilhainvokevirtual “Classe/addTwo(II)I” //chama metodo addTwo da classe “Classe”ireturn //retorna o inteiro do topo da pilha
.end method
Jasmin – Exemplos
• Exemplo de uso de parâmetros e retorno de valores:– Código Java:
double doubleLocals(double d1, double d2){ return d1 + d2;
}
Jasmin – Exemplos
• Exemplo de uso de parâmetros e retorno de valores:– Código Jasmin:.method doubleLocals(DD)D
dload_1 //coloca variável d1 na pilhadload_3 //coloca constante d2 na pilhadadd //soma de doubledreturn //retorna o double do topo da pilha
.end method
Jasmin – Exemplos
• Instanciando um novo objeto:– Código Java:
Object create() {return new Object();
}
Jasmin – Exemplos
• Instanciando um novo objeto:– Código Jasmin:.method create()Ljava/lang/Object;
new “java/lang/Object” //aloca espaço no heapdup //duplica o topo da pilhainvokespecial “java/lang/Object/<init>”//chama o construtor (método “<init>”)areturn //retorna a referência para o objeto
.end method
Jasmin – Exemplos
• Laço for:– Código Java:
void spin() {int i;for (i =0; i < 100; i ++) {
;}
}
Jasmin – Exemplos
• Laço for:– Código Jasmin:.method spin()V
iconst_0 // põe valor zero na pilhaistore_1 // armazena na variável 1 (i=0)goto teste // desvia para o teste do laçolaco: // label do início do lacoiinc 1 1 // incrementa variável 1 (i) de 1teste: // label do teste da condicaoiload_1 // põe variável i na pilhabipush 100 // põe constante 100 na pilhaif_icmplt laco // compara os valores da pilha e desviareturn
.end method
Referências
• The Java Virtual Machine Specification (Lindholm & Yellin)– http://java.sun.com (capítulos 3 a 7)
• WikiPedia – The Free Encyclopedia– http://www.wikipedia.org/wiki/Virtual_machine
• The Core Of Information Technology– http://cne.gmu.edu/itcore/virtualmachine/history
.htm• Jasmin
– http://cat.nyu.edu/meyer/jasmin