Microjava Káio, Estevão e André Sumário da apresentação • JVM - a máquina virtual Java • microJava 701 Java Virtual Machine - JVM • Máquina que executa programas em bytecode • Processador virtual: o Possui seu próprio conjunto de instruções o Manipula diferentes áreas de memória • Baseada em pilha de operandos o Não há registradores visíveis • Responsável por gerenciar: memória (garbage collector), erros, exceções, threads JVM - Base da Especificação • Subsistema o Referente à carga de classes • Área de memória o Área de métodos o Heap o Pilha • Tipos de Dados o Primitivos (numéricos, lógicos e "retorno de endereço"->Ponteiros para opcode da JVM) o Derivados (objetos, classes, interfaces) • Conjunto de instruções JVM - Base da Especificação Java Virtual Machine - JVM Java Virtual Machine - JVM • Suporta multithreading • Um registrador PC (program counter) para cada thread ativa • Um stack para cada thread ativa • Memória dinâmica (heap) compartilhada por todas as threads • Operandos das instruções sempre estão no stack da thread MicroJava-701 Introdução • Lançado em 1998 pela Sun • O primeiro processador que executa bytecode diretamente em hardware. • MicroJava 701 executa bytecodes cerca de duas vezes mais rápido que um Pentium II a 266 MHz • Para execução de bytecode o 701 é provavelmente mais rápido e mais barato do que qualquer outro mecanismo • Dispensa o uso de compiladores Java JIT Características • Núcleo de picoJava 2.0 de 32 bits o A cache da pilha tem 64 entradas o 1 cache de 16KB para instruções e 1 cahe de 16KB para dados o Instruções da JVM o Pipeline de seis estágios • Controladores de barramento de E/S e do sistema de memória Características • Frequência de operação de 133 até 200 MHz • Suporte para ordenação de big e little-endian • Dois barramentos: um de 64 bits para acesso a memória e um PCI de 32 bits • Controlador de interrupção e temporizadores múltiplos. Cache • Cache de Instrução o 16kByte em tamanho o Cache de mapeamento direto organizado em 1024 linhas × 16Byte. o Linha de instrução da cache com 4 palavras de 32-bit. • Cache de Dados o 16kByte em tamanho. o Conjunto de 512 linhas × 16Byte. o Linha de dados da cache com 4 palavras de 32bit. Unidade Inteira (IU) • É ela que busca e carrega as instruções da cache de instruções • Carrega e armazena dados na cache de dados • Não contém nenhum registrador de uso geral visível para o programador • Instruções inteiras JAVA o Definida na especificação da JVM • Suporta instruções de deslocamento, multiplicação e divisão de inteiros e manipulação da pilha • Até quatro instruções podem ser juntadas e executadas em paralelo (VLIW) Unidade de Ponto Flutuante (FPU) • A FPU executa todas as instruções de ponto flutuante - de precisão simples e dupla - definidas pelo JAVA • Segue a especificação da JVM. • Possui: o Seqüenciador de microcódigo o Somador de ponto flutuante o Divisor/multiplicador de ponto flutuante. • float e double representam precisão simples de 32 bits e precisão dupla de 64 bits • Possui um barramento de dados de 32 bits Unidade gerenciadora de pilha (SMU) • É uma memória cache com 3 portas de leitura e duas de escrita • Uma unidade de controle da pilha • Gerenciador de dribble Diagrama de Blocos do mJ701 Mapeamento da Memória • O microJava-701 permite que as regiões de memória sejam colocadas em qualquer lugar dentro de 1GB de espaço enderecável o DRAM (EDO e SDRAM) — quatro bancos o Barramento local — quatro bancos o PCI Memória E/S — três bancos • As regiões fixadas no mapa de memória são as seguintes: o Registradores o O código de inicialização selecionado FLASH_CS#—somente o código inicial é fixo (tamanho da região pode ser programado) Interface com Memória DRAM • Dispositivos DRAM devem ser da mesma tecnologia e grau de velocidade. • Dispositivos DRAM de 32-bit e 64-bit. • O sistema DRAM é organizado como 4 conjuntos que variam de 4 MBytes até 64 MBytes de tamanho. Interface com Memória Flash • 64KByte para 1GByte de memória Flash. • Dados largura do barramento de 8 bits, 16 bits ou 32 bits. Controlador de Interrupção • 15 níveis de interrupção e uma interrupção não mascarada (NMI) • NMI, seis interrupções externas, EXT_INTR [05:00], e quatro interrupções de baixo nível, LL_INTR # [03:00] disponíveis para uso geral. • Quatro fontes de interrupções geradas internamente: o tick timer, o temporizador de uso geral, o watchdog timer o erro de PCI. • Duas interrupções de software. • Uma fonte de interrupção pode ser mapeado para qualquer um dos 15 níveis. Diagrama de Blocos Conjunto de Instruções • Instruções identificadas por opcode de tamanho fixo de 1 byte • Conjunto de instruções não ortogonal • Operações complexas são emuladas via software • Exemplo de uma iteração interna da máquina virtual: do { fetch an opcode; if (operands) fetch operands; execute the action for the opcode; } while (there is more to do); Conjunto de Instruções • As instruções operam apenas sobre um tipo específico. • A instrução tem representado no seu mnemônico o tipo sobre o qual ela opera. • Uma letra para representar cada tipo: o o o o o i : operações sobre int l : operações sobre long f : para float d : para double a : para o tipo referência (classes, arrays, interfaces) Instruções Aritméticas • Dois tipos: o Processamento de valores inteiros o Processamento de valores ponto-flutuante • Não suporta os tipos byte, short, e char o Conversão para int e execução da operação Conjunto de Instruções Aritméticas • • • • • • • • • • • Adição: iadd, ladd, fadd, dadd. Subtração: isub, lsub, fsub, dsub. Multiplicação: imul, lmul, fmul, dmul. Divisão: idiv, ldiv, fdiv, ddiv. Resto da divisão (mod): irem, lrem, frem, drem. Negação: ineg, lneg, fneg, dneg. Deslocamento: ishl, ishr, iushr, lshl, lshr, lushr. OU bit a bit : ior, lor. E bit a bit: iand, land. OU EXCLUSIVO bit a bit: ixor, lxor. Incremento de variável local: iinc. Conjunto de Instruções • Conversões de tipo: o o o o A primeira letra é o tipo origem, a última é o tipo destino. O número 2 tem o sentido de “to” (para). 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, ... Conjunto de 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. o Tamanho do array: arraylength o o o Conjunto de 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. Conjunto de Instruções • Instruções de controle (desvios): o o 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 Conjunto de Instruções • Chamada e retorno de métodos: Chamada: invokevirtual, invokespecial, invokestatic. o Retorno: lreturn, freturn, ireturn. o 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 método “pai”. o Instruções de Carga e Armazenamento • Transferem dados entre as variáveis locais da máquina virtual e operandos da pilha: iload, iload_<n>, lload, lload_<n> fload, fload_<n>, dload, dload_<n> aload, aload_<n>