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
Máquinas Virtuais
• 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 para LP´s
•
•
•
•
•
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
JVM - Introdução
• 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
Java Bytecode
JVM
Sistema Operacional
Hardware
Arquivo class
• 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
Tipos de Dados
• 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 Primitivos
• 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
Tipo Referência
• É 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
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
Frames
• 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
Pilha de
Operandos
Frame 5
0
1 2
3
4
5
Frame 4
Frame 3
Ref. Constant Pool
Frame 2
Frame 1
JVM Stack
0
1
2
...
<Class>
“My Class”
<String> “Hello World”
<Integer> 1234567
...
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
5
...
4
3
3
4 bipush 10
31
33
6
2
23
iload_2
iadd
7 istore_3
1
10
0
33
23
...
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:
dcmpg
ifeq loop
– Switch: tableswitch, lookupswitch
Instruções
5
...
4
5
3
6 ifeq 11
9
2
fcmpg
aconst_null
10 astore_2
1
1.0
1.0
11 fload_0
0
5.43
5.43
0
1.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.java
public 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()I
aload_0
//coloca variável zero na pilha (this)
bipush 12 //coloca constante 12 na pilha
bipush 13 //coloca constante 13 na pilha
invokevirtual “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 pilha
dload_3
//coloca constante d2 na pilha
dadd
//soma de double
dreturn
//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 heap
dup
//duplica o topo da pilha
invokespecial “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
istore_1
goto teste
laco:
iinc 1 1
teste:
iload_1
bipush 100
if_icmplt laco
return
.end method
//
//
//
//
//
//
//
//
//
põe valor zero na pilha
armazena na variável 1 (i=0)
desvia para o teste do laço
label do início do laco
incrementa variável 1 (i) de 1
label do teste da condicao
põe variável i na pilha
põe constante 100 na pilha
compara os valores da pilha e desvia
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.ht
m
• Jasmin
– http://cat.nyu.edu/meyer/jasmin
Download

JVM- Máquina Virtual Java