2

Click here to load reader

[Magill 03] resume

Embed Size (px)

DESCRIPTION

Implementando Escape Analysis no Jikes RVM

Citation preview

Page 1: [Magill 03] resume

set-2011

I. INTRODUÇÃO

o artigo [1], os autores citam a contribuição de Choi et al. que, num esforço em limitar o número de objetos

alocados dinamicamente e reduzir o overhead de sincronização, introduziram um novo algorítimo para determinar estaticamente se um dado objeto “escapa” seu método ou linha de execução (thread) [2]. Em particular, Choi et al. introduziram uma nova representação estática do estado do programa chamada de grafo de conexão (connection graph) e uma análise de fluxo de dados (data flow analysis – DFA) baseada neste estado. Enquanto Choi et al. realizaram suas analises em um compilador estático, High Performance Compiler for Java – HPCJ, os autores implementaram suas analises como um passo de otimização em tempo de execução (run-time optimization) no Jikes Research Virtual Machine – Jikes RVM [3]. Os autores perceberam no entanto que há um custo de performance significativo neste tipo de análise quando aplicada em tempo de execução, porém os resultados indicaram que algumas analises adicionais podem oferecer oportunidades para uma execução mais eficiente em programas de tempo de execução longos.

N

Para endereçar estes problemas, os autores propuseram então modificações requeridas neste tipo de analise para serem realizadas no contexto de um sistema de otimização em tempo de execução. Este resumo traz uma visão geral da analise usada pelos autores.

II. ESCAPE ANALYSIS

Park e Goldberg introduziram o termo Escape Analysis para descrever a analise que determina que partes de uma lista não escapa de uma chamada de função. No contexto da linguagem de programação Java estamos interessados em determinar se um objeto ou vetor (array) não escapa o método que o invocou ou sua thread de execução. Para cada alocação ou atribuição no programa, representa-se seu estado corrente como um grafo de conexão. Nós são adicionados para representar a alocação de objetos ou arrays, bem como as referências a estas alocações, seus campos e elementos. Atribui-se a cada nó os valores GLOBAL_ESCAPE, THREAD_LOCAL ou METHOD_LOCAL para indicar o

O trabalho em referência foi apresentado na conferência PACT'07 realizado entre os dias 15 e 19 de setembro de 2007 na cidade de Brasov, Romenia. O resumo é parte do trabalho de pesquisa de doutorado do Instituto de Computação da UNICAMP (IC-Unicamp) e foi elaborado por Pereira, M. M. (e-mail: [email protected] ).

estado da variável ou objeto representado pelo nó. Arestas representam tanto as referências criadas por atribuições ou referências de um objeto para os seus campos. Nos nós de intersecção do programa, simplesmente faz-se a união dos grafos a partir dos nós predecessores.

Escape analysis possibilita ao compilador realizar dois tipos de otimização: ela indica ao compilador oportunidades para alocação de memória mais restritiva e, portanto, de baixo custo, e oportunidades de remoção de operações de sincronização desnecessárias. Em Java, objetos e arrays são criados pelo operador new, alocados no heap e gerenciados por algum tipo de gerenciamento automático de memória ou coleta de lixo (garbage collection).

Através da análise se há ou não referências a um objeto fora do método que o alocou ou da sua thread de execução, podemos colocar um limite superior conservador ligado à vida do objeto. Se o compilador puder determinar estaticamente que um objeto não sobreviverá ao método que o alocou, o código pode ser transformado para usar uma das técnicas descritas a seguir: o armazenamento do objeto pode ser vinculado ao registro de ativação do método.

III.SCALAR REPLACEMENT AND STACK ALLOCATION

Os autores usaram esta forma de Scape Analysis para realizar uma otimização chamada de Scalar Replacement of aggregates. Ao invés de alocar objetos e pequenos arrays no heap, eles são definidos na pilha ou mesmo em registradores. No Jikes RVM esta otimização é realizada sob a representação intermediária HIR (High-level Intermediate Representation). Neste estágio de compilação, pilha e registradores são referenciados uniformemente como registradores virtuais. Com isto, a otimização pode ser realizada independente de máquina e tirar proveito do passo de alocação de registradores. Em contrapartida, há uma série de restrições sobre estes objetos e arrays considerados para replacement. O tamanho dos arrays, bem como todas as operações de indexação, precisam ser determinados estaticamente. Além disso, objetos e arrays não podem ser usados com certas operações que requerem uma referência para os mesmos (e.g., invoke).

Choi et al. descrevem uma forma de alocação similar, mas distinta, conhecida como Stack Allocation. Ao invés de atribuir campos individuais ou elementos para registradores virtuais, aloca-se o objeto inteiro ou array na pilha, incluindo qualquer informação de cabeçalho associada ao objeto ou

1

Implementing Escape Analysis in the Jikes RVM

Stephen Magill Daniel Spoonhower

April 28, 2003

Resumo realizado por Marcio Machado Pereira – RA 780681

Page 2: [Magill 03] resume

set-2011

array. Stack Allocation é, em muitos casos, menos restritivo que Scalar Replacement, porém ela não é independente de plataforma. Como o compilador trabalha neste caso com endereços de memória ao invés de registradores virtuais que pode ou não ser mapeado em memória, Stack Allocation suporta, por exemplo, operações com indices de arrays não constantes.

A fim de identificar corretamente as oportunidades para o uso de Scalar Replacement, os autores tiveram que fazer várias modificações no algoritmo dado em [2], que é orientado para Stack Allocation:

Quando um objeto é alocado na pilha, tem-se ainda um ponteiro para um bloco de memória contendo o objeto. Com Scalar Replacement, nenhum pointeiro para o objeto está disponível. O primeiro problema que isto causa é quando uma variável de referência x aponta para objetos diferentes em caminhos diferentes através do código. Se pelo menos um desses objetos “escapa”, devemos alocar todos os objetos referenciados por x no heap, pois em algum ponto, x conterá um endereço de um objeto real. A solução dada pelos autores para isso foi o de propagar estas informações para trás e para frente durante a fase de propagação do algoritmo. O estado escape de um nó de referência é definido como o encontro dos estados escape dos objetos que ele aponta (backward propagation). Esta informação é então propagada para frente (forward propagation) para os objetos. Esta sequencia de propagações backward/forward é repetida até que se convirga para um ponto fixo. Isto é ilustrado na figura abaixo:

O segundo problema ocorre com instruções do tipo a = b, que corresponde a instruções ref_move no Jikes RVM. A única chance razoável de lidar com isso é quando a e b são marcados como método local. Pode-se ir em frente substituindo todos os usos de a.x com o escalar correspondente b.x no entanto, há que se analisar todos os usos de a para garantir que esta substituição é válida. Um

exemplo de quando a substituição não é válida é dada na figura abaixo:

A idéia deste Scalar Repacement é muito similar ao Copy Propagation. De fato, ele é válido exatamente quando Copy Propagation é permitido. A última alteração é a inclusão do valor BOUNDED_BY_METHOD. Este nome reflete o fato de que os argumentos passados para os procedimentos escapam do escopo estático do chamador, mas eles podem ser alocados na pilha uma vez que sua vida útil é limitada pelo tempo de vida do método chamado.

IV.CONCLUSÃO

No contexto estático, o custo de um passo de otimização é muito menos importante do que os resultados. Já em um sistema de otimização em tempo de execução, o custo de cada passo deve ser considerado em relação ao benefício de seu resultado, seja em termos de tempo de execução ou redução dos requisitos de memória. Tem-se afirmado frequentemente que a análise de fluxo de dados é muito cara para uso em tempo de execução. A experiência dos autores fundamenta essa afirmação. Mas, ao mesmo tempo, parece haver benefício significativo para otimizações como a alocação de pilha e eliminação de sincronização. Com base nos resultados obtidos, valeria a pena considerar análises mais rápidas e que permitam que estas otimizações sejam baseadas no formato SSA do programa.

V. REFERENCIAS

[1] S. Magill, D. Spoonhower. Implementing Escape Analysis in the Jikes RVM. April 28, 2003.

[2] Jong-Deok Choi, Manish Gupta, Mauricio J. Serrano, Vugranam C. Sreedhar, and Samuel P. Midkiff. Escape analysis for Java. In Proceedings of the Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA), pages 1-19, 1999.

[3] B. Alpern, C. R. Attanasio, J. J. Barton, M. G. Burke, P. Cheng, J.-D. Choi, A. Cocchi, S. J. Fink, D. Grove, M. Hind, S. F. Hummel, D. Lieber, V. Litvinov, M. F. Mergen, T. Ngo. J. R. Russell, V. Sarkar, M. J. Serrano, J. C. Shepherd, S. E. Smith, V. C. Sreedhar, H. Srinivasan, and J. Whaley. The Jalapeño virtual machine. IBM Systems Journal, 39(1):2111-238, 2000.

2