Coleta de lixo sem tags para linguagens orientadas a objetos

7

Estou procurando uma boa técnica de coleta de lixo para o meu idioma e encontrei este artigo , onde Benjamin Goldberg descreve uma técnica de coleta de lixo para linguagens fortemente tipadas, o que elimina a necessidade de informações de tipo durante o tempo de execução.

Resumidamente, isso é feito colocando um ponteiro para uma função de coleta de lixo logo após uma chamada de função, diretamente no código compilado. Eles então estendem isso para apoiar o polimorfismo paramétrico do tipo ML.

Agora, minha pergunta : houve algum trabalho sobre como essa técnica poderia ser implementada em uma linguagem orientada a objetos, onde muita funcionalidade é implementada por meio de chamadas indiretas usando ponteiros em uma tabela virtual?

MathiasVP
fonte
O que você vê como um problema? O que importa é que cada entidade conheça sua própria identidade de armazenamento.
babou 9/07/2014
Sim, mas, no meu cenário, não se sabe em tempo de compilação qual função é chamada e, portanto, a gc_routine (terminologia do artigo) a ser chamada durante a coleta de lixo não é conhecida em tempo de compilação. Estou procurando uma solução para esse problema, sem recorrer a um método GC interpretado.
precisa saber é o seguinte
Tentei responder à sua pergunta, conforme tornado mais preciso no comentário, mas estou me perguntando se esse é realmente o problema que você tem em mente. Comentários são bem-vindos.
babou 9/07/2014
parece que você simplesmente precisa de uma indireção de tempo de execução no sistema gc que corresponde à função de indireção. Observe que há muitos sistemas de recolha de lixo, é apenas uma questão de encontrar um que corresponda ao seu projeto de linguagem ....
vzn

Respostas:

6

Como o sorvete Häagen-Dazs , a Orientação a Objetos tem muitos sabores, embora com mais nozes e bananas. Por isso, é perigoso responder à sua pergunta apresentada em termos muito gerais. Linguagens OO específicas podem ter recursos inesperados que podem gerar problemas com métodos virtuais. Temo que tentar imaginar que tipo de recursos possa fazer as coisas darem errado seja um exercício infrutífero. É melhor tentar responder a perguntas precisas.

O princípio básico do GC sem tags é que, a qualquer momento, você deve poder inspecionar a memória iniciando na pilha e conhecer o tipo real de todos os blocos de memória alocada ao vivo (porque é exatamente isso que o GC precisará trabalhar). Isso implica também saber, em cada ponto de chamada de uma função / método, o estado atual do bloco de ativação do chamador, seja na pilha ou na pilha, ou seja, as variáveis ​​atuais do bloco e seu estado de inicialização. As informações estruturais necessárias podem ser armazenadas como descritores de dados a serem interpretados ou como rotinas gc executáveispara melhor eficiência do GC. O ponto importante do GC sem tags é que essas informações podem ser determinadas estaticamente, para serem armazenadas uma vez com o código e não com cada instância de um tipo ou classe ou de ativação de função. Quando essas informações podem mudar dinamicamente, como é o caso dos tipos polimórficos, deve ser possível calculá-las rastreando e compondo as informações do tipo estático por meio da sequência de chamadas dinâmica.

O fato de um método ser virtual e chamado através de uma tabela virtual não é, por si só, um problema. Um chamador não precisa saber o que está chamando, pois não tem importância em relação ao GC para seu próprio registro de ativação . O destinatário deve conhecer a si mesmo (o compilador cuida dele) e transportar todas as informações necessárias. As informações podem estar incompletas, como no caso do polimorfismo, e devem ser preenchidas com outras informações de tipo disponíveis na sequência de chamadas. Na verdade, em um idioma como o ML, no qual as funções podem ser passadas como parâmetros ou colocadas em tuplas, o chamador pode não saber para qual função está realmente chamando.

O que importa é que o chamador saiba onde, em seu código, chama o chamado, para determinar o estado do seu bloco de ativação durante a chamada. Isso depende estaticamente do ponto de chamada e, portanto, pode ser inferido a partir do endereço de retorno do destinatário (de várias maneiras, dependendo das variações técnicas usadas por diferentes autores). O correspondente gc-routine pode, portanto, ser encontrado de alguma forma a partir desse endereço de retorno. Por exemplo, ele pode estar no código logo após a chamada, mas outras técnicas equivalentes podem ser consideradas. Portanto, se o chamado for interrompido pelo GC, será possível fazer o GC para o registro de ativação dos chamadores. O chamador não trabalha com o GC para o receptor, apenas para seu próprio registro de ativação.

O que pode ser um problema é garantir que o receptor saiba o tipo real de todos os valores que são passados ​​para ele (como no polimorfismo). Mais precisamente, deve ser possível encontrar essas informações quando o GC ocorrer e deve lidar com o registro de ativação do método real que é acessado através de um virtual.

Acredito que ser mais preciso nesta última questão depende dos recursos e estruturas de classe / objetos reais da linguagem OO, de sua organização de digitação.

Mas, como o chamador não precisa conhecer o chamado, não vejo que as chamadas indiretas possam ser um problema.

Outro ponto (respondendo ao comentário do OP) é ​​que o problema aqui não é se o GC é executado a partir de código compilado ou interpretado a partir de descritores, mas se ele precisa de tag dinâmico para informações de tipo.

Sugestão : para encontrar mais trabalho sobre isso, pegue seus mecanismos de pesquisa favoritos (e outros recursos da web) e procure documentos que citam os documentos de Goldberg ou suas referências principais. Aplique o procedimento recursivamente, adicionando palavras-chave ocasionais, como orientadas a objetos ou virtuais .

babou
fonte