Buscar

11 ambienteExecucao e geracaoDeCodigo Edjan Sobral Verissimo Michiles

Prévia do material em texto

IF688 – Ambiente de Execução e Geração de Código
Estado de um programa
Execução de um programa é resultado de uma sequência de transições de estado
S1  S2 ...  Sn
Estado Inicial
Estado Final
Componentes
Área estática: espaço para meta-dados associados ao código
Heap: espaço reservado para alocação dinâmica de memória
Program Counter (PC): instrução corrente
Pilha: Contexto de chamada de funções
Componentes
Área estática: espaço para meta-dados associados ao código
Heap: espaço reservado para alocação dinâmica de memória
Program Counter (PC): instrução corrente
Pilha: Contexto de chamada de funções
Um PC e Pilha para cada thread do programa!
Área estática
Representação do código
Instruções (e.g., métodos)
Estrutura de dados
Exemplo
public class Foo {
 public static void main(String[] args){
 int t = 10;
 t += t + 1;
 }
}
$ javac Foo.java
$ javap -classpath . -c Foo
Exemplo
$ javac Foo.java
$ javap -classpath . -c Foo
class Foo extends java.lang.Object{
Foo();
 Code:
 0: aload_0
 1: invokespecial #1; //Method java/lang/Object."<init>":()V
 4: return
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
É preciso saber que código será executado e identificar variáveis globais do programa! 
Java bytecodes
Total de 204 instruções
Próximo de 100 quando consideramos apenas uma por grupo (iadd, dadd, etc.)
Veja: http://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html
Pilha
Fluxo de controle de chamadas de funções
Cada frame da pilha corresponde ao registro de ativação de uma função.
Criada pelo chamador da função
Pilha
Em C, armazena apenas os registros de ativação das chamadas de funções
Em Java, a pilha também é usada na interpretação de instruções
Exemplo
$ javac Foo.java
$ javap -classpath . -c Foo
class Foo extends java.lang.Object{
Foo();
 Code:
 0: aload_0
 1: invokespecial #1; //Method java/lang/Object."<init>":()V
 4: return
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
10
?
Reservado para variáveis locais
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
10
Reservado para variáveis locais
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
10
10
Reservado para variáveis locais
10
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
10
10
Reservado para variáveis locais
10
1
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
10
10
Reservado para variáveis locais
11
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
21
10
Reservado para variáveis locais
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
21
Reservado para variáveis locais
Exemplo para um procedimento
public static void main();
 Code:
 0: bipush 10
 2: istore_0
 3: iload_0
 4: iload_0
 5: iconst_1
 6: iadd
 7: iadd
 8: istore_0
 9: return
}
21
Retorna ao chamador

O registro de ativação contém endereço para onde o controle deve retornar. Isto é, próximo PC.
Exemplo para vários procedimentos
public class Foo {
 public static void main(String[] args){
 bar(10);
 }
 static void bar(int t){
 t += t + 1;
 }
}
Exemplo para vários procedimentos
public class Foo {
 public static void main(String[] args){
 bar(10);
 }
 static void bar(int t){
 t += t + 1;
 }
}
main
10
Exemplo para vários procedimentos
public class Foo {
 public static void main(String[] args){
 bar(10);
 }
 static void bar(int t){
 t += t + 1;
 }
}
main
bar
10
main
10
Exemplo para vários procedimentos
public class Foo {
 public static void main(String[] args){
 bar(10);
 }
 static void bar(int t){
 t += t + 1;
 }
}
main
bar
10
main
10
...
bar
main
10
10
Exemplo para vários procedimentos
public class Foo {
 public static void main(String[] args){
 bar(10);
 }
 static void bar(int t){
 t += t + 1;
 }
}
main
bar
10
main
10
...
bar
main
10
10
Referência para variáveis locais e parâmetros do procedimento.
Heap
Grafo 
Nós correspondem as alocações dinâmica de dados
Aresta correspondem a referências para tais dados a partir de dados alocados dinâmicamente
Referências podem partir da pilha ou da área estática também
Exemplo
public class Tree {
 Node root;
 static class Node {
 Node l, r; int val;
 Node(int v) { val = v; }...
 }
 Tree(int v) {
 if (root == null) root = new Node(v);
 else ...
 } ...
}
Exemplo
public class Tree { ... 
 public static void main(String[] args){
 Tree t = new Tree(5); 
 }
}
root
val=5, 
l= null , r=null
Objetos estão na heap! Instâncias não alcançáveis a partir da pilha ou campos estáticos estão sujeitas a garbage collection!
27
Memory Leaks
O programador pode esquecer de liberar espaço de memória
Em C(++), usa-se explicitamente comando (delete) para liberar objetos alcançáveis por uma determinada referência
Em Java, o programador precisa liberar referência para objetos
Memory Leaks: Exemplo
Heap
p
Neste cenário, objeto referenciado por p não é mais usado. Porém, o programador esqueceu de liberar o objeto aponta por p!
Memory Leaks: Exemplo
Heap
p
Heap
p
null
Este cenário mostra o objeto sendo liberado. Os nós em cor escura estão disponíveis para coleta.
Garbage collection (Mark-Sweep)
Heap
Garbage collection (Mark-Sweep)
Heap
Garbage collection (Mark-Sweep)
Heap
Garbage collection (Mark-Sweep)
Heap
Heap e Pilha
public class Tree { ... 
 public static void main(String[] args){
 Tree t = new Tree(5); 
 }
}
$ javap -classpath . -c Tree
public class Tree extends java.lang.Object{
public static void main(java.lang.String[]);
 Code:
 0: new #2; //class Tree
 3: dup
 4: iconst_5
 5: invokespecial #3; //Method "<init>":(I)V
 8: astore_1
 9: return
}}
Heap e Pilha
root=null
$ javap -classpath . -c Tree
public class Tree extends java.lang.Object{
public static void main(java.lang.String[]);
 Code:
 0: new #2; //class Tree
 3: dup
 4: iconst_5
 5: invokespecial #3; //Method "<init>":(I)V
 8: astore_1
 9: return
}}
?
?
Heap e Pilha
root=null
$ javap -classpath . -c Tree
public class Tree extends java.lang.Object{
public static void main(java.lang.String[]);
 Code:
 0: new #2; //class Tree
 3: dup
 4: iconst_5
 5: invokespecial #3; //Method "<init>":(I)V
 8: astore_1
 9: return
}}
?
?
Heap e Pilha
root=null
$ javap-classpath . -c Tree
public class Tree extends java.lang.Object{
public static void main(java.lang.String[]);
 Code:
 0: new #2; //class Tree
 3: dup
 4: iconst_5
 5: invokespecial #3; //Method "<init>":(I)V
 8: astore_1
 9: return
}}
?
5
?
Heap e Pilha
root
val=10, 
l= null , r=null
$ javap -classpath . -c Tree
public class Tree extends java.lang.Object{
public static void main(java.lang.String[]);
 Code:
 0: new #2; //class Tree
 3: dup
 4: iconst_5
 5: invokespecial #3; //Method "<init>":(I)V
 8: astore_1
 9: return
}}
?
?
Heap e Pilha
root
val=10, 
l= null , r=null
$ javap -classpath . -c Tree
public class Tree extends java.lang.Object{
public static void main(java.lang.String[]);
 Code:
 0: new #2; //class Tree
 3: dup
 4: iconst_5
 5: invokespecial #3; //Method "<init>":(I)V
 8: astore_1
 9: return
}}
?
Heap e Área Estática
...ou dados e código
Como organizar os dados ?
Como implementar dynamic binding ?
Exemplo
class Point {
 protected int x,y;
 public Point (int x, int y) {
 this.x=x; this.y=y;
 }
 public void move(int dx, int dy) {
 this.x += dx; this.y += dy;
 }
 public float area() {
 return 0.0;
 }
 public float dist(Point that) {
 int dx= this.x – that.x;
 int dy= this.y – that.y;
 return Math.sqrt(dx*dx + dy*dy);
 }
}
Exemplo 1: código
 init
move
area
dist
x
y
x
y
x
y
Instâncias
Heap
Área Estática
Exemplo 2: atualização de estado
Construtor
move
area
dist
Heap
Point p = new Point(2,3);
Point q = new Point(0,0);
p
q
0
0
2
3
Área Estática
Pilha
Exemplo 2: atualização de estado
Construtor
move
area
dist
Heap
Point p = new Point(2,3);
Point q = new Point(0,0);
p
q
0
0
3
4
p.move(1,1);
Área Estática
Pilha
Exemplo 2: atualização de estado
Construtor
move
area
dist
Heap
Point p = new Point(2,3);
Point q = new Point(0,0);
p
q
0
0
3
4
p.move(1,1);
q = p;
Área Estática
Pilha
Dynamic binding
class Circle extends Point {
 protected int r;
 public Circle (int x, int y, int r) {
 this.x = x; this.y = y; this.r = r;
 }
 public int radius() { return this.r; }
 public double area() { 
 double pi=3.1416; 
 return pi*this.r*this.r;
 }
}
class Box extends Point {
 protected int w,d;
 public Box (int x, int y, int w, int d) {
 this.x = x; this.y = y; 
 this.d=d; this.w = w;
 }
 public int width() { return this.w; }
 public int depth() { return this.d; }
 public double area() { 
 return (double) this.w * this.d;
 }
}
Criação de objetos e herança
Construtor
move(herdado)
area(sobreposto)
dist(herdado)
radius
Construtor
move(herdado)
dist(herdado)
area(sobreposto)
width
depth
Heap
0
12
4
0
4
8
8
p
c
b
Área Estática
Pilha
 
Point p = null;
Circle c = new Circle(0,12,4); Box b = new Box(0,4,8,8);
Polimorfismo
Construtor
move(herdado)
area(sobreposto)
dist(herdado)
radius
Construtor
move(herdado)
dist(herdado)
area(sobreposto)
width
depth
20
32
4
0
4
8
8
p
c
b
a
50.3
p = c;
p.move(20,20);
double a = p.area();
Área Estática
Pilha
Heap
Geração de código
Assembler é usado para isolar programador de detalhes de implementação
Exemplos: jasmin, ilasm
Vamos usar MS ilasm.exe
Entrada: MSIL (Microsoft Intermediate Language)
Saída: código nativo
Exemplo: Entrada de ilasm (1/3)
// Metadata version: v2.0.50215
.assembly extern mscorlib
{
 .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
 // .z\V.4..
 .ver 2:0:0:0
}
.assembly sample
{
 .custom instance void
 [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32)
 = ( 01 00 08 00 00 00 00 00 ) 
 .hash algorithm 0x00008004
 .ver 0:0:0:0
}
.module sample.exe
// MVID: {A224F460-A049-4A03-9E71-80A36DBBBCD3}
.imagebase 0x00400000
// .......................SEE NEXT SLIDE
Exemplo: Entrada de ilasm (2/3)
// SEE PREVIOUS SLIDE
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02F20000
// =============== CLASS MEMBERS DECLARATION ===================
.class public auto ansi beforefieldinit Hello
 extends [mscorlib]System.Object {
 .method public hidebysig static void Main(string[] args) cil
 managed {
 .entrypoint
 // Code size 13 (0xd)
 .maxstack 8
 IL_0000: nop
 IL_0001: ldstr "Hello World!"
 IL_0006: call void
 [mscorlib]System.Console::WriteLine(string)
 IL_000b: nop
 IL_000c: ret
 } // ....................... SEE NEXT SLIDE
Exemplo: Entrada de ilasm (3/3)
// SEE PREVIOUS SLIDE
 .method public hidebysig specialname rtspecialname 
 instance void .ctor() cil managed
 {
 // Code size 7 (0x7)
 .maxstack 8
 IL_0000: ldarg.0
 IL_0001: call instance void
 [mscorlib]System.Object::.ctor()
 IL_0006: ret
 } // end of method Hello::.ctor
} // end of class Hello
Detalhes de MSIL e uso do ilasm em aula de laboratório.

Continue navegando