Departamento de Estatística e Informática Universidade Federal de Sergipe Compiladores Registros de Ativação Giovanny Lucero [email protected] 1 Introdução • Funções podem ter variáveis locais – Criadas dinamicamente na “entrada” da função – Várias instâncias da mesma função podem existir ao mesmo tempo (quando?) – Cada instância tem suas próprias vars. locais int f (int x) { int y; y = x+x; if (y<10) y = f(y); else y = y-1; return y } 2 Pilha e funções de alta ordem • Em muitas linguagens imperativas temos: – Variáveis locais são destruídas na saída – Alocação e destruição de variáveis locais tem um comportamento LIFO (pilha) • Com aninhamento de funções e funções de alta ordem (juntos), não é assim. Ex. def f(x) : def g(y) return x + y; return g; a = f(4); b = a(5); -- uma função onde “x” não foi destruído 3 Registros de Ativação • Também conhecidos como stack frames • Representa o formato dos dados manipulados na execução de um subprograma • Uma instância de um registro de ativação é criada dinamicamente na chamada a um subprograma • Pilha de chamadas é uma pilha de frames • Implementada como um “array” com um ponteiro indicando o topo da pilha 4 • O projeto dos frames deve levar em conta – O conjunto de instruções da arquitetura • Fabricantes prescrevem um frame padrão – Permite inter-operação entre diferentes linguagens – A linguagem sendo compilada • Deve existir uma infra-estrutura em tempo de execução 5 Modelo de um stack frame Argumentos de entrada Vars. locais de sub-blocos Argumentos Variáveis Locais Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos Registradores salvos ponteiro para o topo do registro de ativação do chamador ponteiro para a base do registro de ativação do pai estático ponteiro para o código Argumentos de saída 6 Modelo de um stack frame Endereços mais altos Argumentos Variáveis Locais crescimento da pilha Endereços mais baixos Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos 7 Modelo de um stack frame ponteiro do frame (FP) ponteiro da pilha (SP) Argumentos Variáveis Locais Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos Possui dois ponteiros para . FP que aponta para o início do Frame atual e SP que aponta para o final da pilha. 8 Funcionamento ponteiro do frame (FP) ponteiro da pilha (SP) Argumentos Variáveis Locais Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos 1. O subprograma atual faz chamada a um outro subprograma. 9 Funcionamento 2. Um novo frame é alocado. Os ponteiros FP e SP devem ser atualizados. ponteiro do frame ponteiro da pilha Argumentos Variáveis Locais Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos Variáveis Locais Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos O novo FP = FrameSize - SP. O antigo FP é guardado em memória SP sempre aponta para o início da pilha. 10 Funcionamento 3. Ao desalocar o frame. FP e SP são restaurados ponteiro do frame ponteiro da pilha Argumentos Variáveis Locais Temporais Registradores Vínculo dinâmico Vínculo Estático Endereço de retorno Argumentos 11 • O formato do registro de ativação é estático mas seu tamanho pode ser dinâmico. Por que? • Vínculo estático serve para acessar variáveis não locais • Vínculo dinâmico para destruir (desempilhar) o corrente registro de ativação, no fim da chamada 12 Vínculos estático e dinâmico Main var x .. frames A Main C C() ... x x B A B A() B() C estático dinâmico 13 Registradores • Muito mais velozes que memória – vars. locais, valores intermediários, etc. • Precisam ser salvos para reuso por outra função – Quem salva, quem restaura? • Caller-save – Quando a “função que chama” é responsável por salvar/restaurar • callee-save – Quando a “função chamada” é responsável por salvar/restaurar • Salvar pode ser desnecessário – Var. local que não vai ser usada após uma chamada • È preciso um alocador de registradores 14 Passagem de parâmetros • Alguns parâmetros (até 4, por ex.) são passados em registradores • Salva-se (do chamador) só quando necessário – Procedimentos folhas – Alocação interprocedural – O parâmetro é uma variável morta no momento da chamada a outra função – Janelas de registradores (oferecidos por algumas arquiteturas) • Resultado de função é devolvido em registrador 15 Endereço de retorno • Quando g chama f, eventualmente f termina – Aonde volta o fluxo de controle? • Onde passar o endereço de retorno? – Na pilha (máquinas dos anos 70) – Em registrador • Tráfico evitado em procedimentos folha 16 Variáveis residentes no frame • Em resumo, registradores contém – Parâmetros, endereço de retorno, retorno da função, variáveis locais e valores intermediários • Usa-se obrigatoriamente memória quando: – A variável é passada por referência – Variável de um procedimento mais externo é acessada por procedimento aninhado. – O valor é grande – A variável é um array – aritmética para acesso – O registrador é necessário para outro propósito – Não há suficientes registradores 17 Variáveis residentes no frame • Usamos sempre memória para variáveis que escapam – Variáveis escapadas são aquelas passada por referência, seu endereço é pego (& C/C++), ou é acessada por uma função aninhada • Cálculo de escapes pode requerer duas passadas • Quando é decidido se uma variável vai num registrador? Na elaboração da declaração? 18 Implementação dos Frames • Frames dependem da máquina, mas queremos deixar a análise semântica independente da máquina usada package Frame; public abstract class Access {...} public abstract class Frame { abstract public Frame newFrame(Label name, List /*of bool*/ formals); public Label name; public List /*of Access*/ formals; abstract public Access allocLocal(boolean escape); .... } Obs. Access é um TAD Frame usa Factory method 19 Modularização dos Frames Camadas de abstração lps.semantica – Frame, Acess, Temp e Label Translate provêem visões lps.traducao independentes de máquina Frame Access Temp Label – Translate permite separar análise semântica da frame temp tradução 20 Implementação dos Frames • Encapsula – A locação dos parâmetros formais – O número de variáveis locais alocadas – O “endereço” do código da função 21