Pergunta

O que é a diferença entre o compilador JIT e CLR? Se você compilar seu código para il e CLR executa esse código, então o que está fazendo o JIT? Como a compilação JIT mudou com a adição de genéricos para o CLR?

Foi útil?

Solução

O JIT é um aspecto do CLR.

Especificamente, é a parte responsável por mudar CIL / MSIL (doravante denominado IL) produzido pelo compilador da língua original (csc.exe para Microsoft C #, por exemplo) em código nativo máquina para o processador atual (e arquitetura que ele expõe em o processo actual, por exemplo, 32/64 bits). Se o conjunto em questão foi ngen'd então o processo JIT é completamente desnecessário e o CLR executar esse código muito bem sem ele.

Antes de um método é usado, que ainda não foi convertido a partir da representação intermediária é de responsabilidade do JIT para convertê-lo.
Exatamente quando o JIT vai chutar é específico de implementação, e sujeito a alteração. No entanto, os mandatos de design CLR que o JIT acontece antes os executa código relevantes, da JVM em contraste estaria livre para interpretar o código por um tempo, enquanto um segmento separado cria uma representação código de máquina.
O 'normal' CLR usa um pré-JIT abordagem esboço onde por métodos são JIT compilado apenas como eles são usados. Isto envolve ter o método inicial topo nativa ser uma dissimulação para instruir o JIT para compilar o método então modificar a chamada original para ignorar o esboço inicial. A edição compacta atual em vez compila todos os métodos em um tipo quando ele é carregado.

Para lidar com a adição de Genéricos.

Esta foi a última grande mudança com a especificação IL e JIT em termos de sua semântica em oposição aos seus detalhes internos de implementação.

foram adicionados

Várias novas instruções IL, e opções de dados mais meta foram fornecidos para instrumentar tipos e membros. Restrições foram adicionados ao nível IL também.

Quando o JIT compila um método que tem argumentos genéricos (quer explicitamente quer implicitamente por meio da classe contendo) pode configurar diferentes caminhos de código (instruções de código de máquina) para cada tipo utilizado. Na prática, o JIT usa uma implementação compartilhada para todos os tipos de referência desde variáveis ??para estes exibem a mesma semântica e ocupam o mesmo espaço (IntPtr.Size).

Cada tipo de valor terá código específico gerado por ela, lidar com o reduzido aumento do tamanho / das variáveis ??na pilha / pilha é uma das principais razões para isso. Além disso, emitindo o código de operação restrita antes chamadas de método muitas invocações em tipos não de referência não precisa caixa Valor para chamar o método (essa otimização é usado em casos não genéricos também). Isso também permite que o comportamento default<T> a ser tratado corretamente e para comparações com nulo para ser retirados como há ops (sempre falso) quando um tipo de valor não Nullable é usado.

Se for feita uma tentativa em tempo de execução para criar uma instância de um tipo genérico através da reflexão, em seguida, os parâmetros de tipo serão validados pelo tempo de execução para garantir que eles passam quaisquer restrições. Isso não afeta diretamente o JIT, a menos que este é usado dentro do sistema de tipo (improvável que possível).

Outras dicas

Você compilar o código de IL que é executado e compilado para código de máquina durante a execução, isso é o que é chamado JIT.

Editar , a carne para fora a resposta um pouco mais (ainda excessivamente simplificado):

Quando você compilar o código C # no Visual Studio fica transformado em IL que o CLR entende, o IL é o mesmo para todos os idiomas em execução no topo da CLR (que é o que permite que o tempo de execução .NET para usar vários idiomas e inter-op facilmente entre eles).

Durante a execução do IL é interpretado em código de máquina (que é específico para a arquitetura que está diante) e, em seguida, ele é executado. Este processo é chamado de compilação Just In Time ou JIT para breve. Apenas o IL que é necessário é transformada em código de máquina (e apenas uma vez, é "cache" uma vez que é compilado em machinecode), apenas no tempo antes de ser executado, daí o nome JIT.

Isto é o que seria semelhante para C #

C # Código > C # Compiler > IL > .NET Runtime > JIT Compiler > Machinecode > Execução

E este é o que olharia como para VB

Código VB > VB Compiler > IL > .NET Runtime > JIT Compiler > Machinecode > Execução

E como você pode ver apenas as duas primeiras etapas são exclusivos para cada idioma, e tudo depois de ter sido transformado em IL é o mesmo que é, como eu disse antes, a razão que você pode executar várias línguas diferentes no topo do. NET

Como Jon Skeet diz, JIT faz parte do CLR. Basicamente é isso que está acontecendo sob o capô:

  1. O seu código fonte é compilado em um know código byte como o idioma intermediário comum (CIL).
  2. metadados de cada classe e todos os métodos (e qualquer outra coisa: O). Está incluído no cabeçalho PE do executável resultante (seja ele uma dll ou um exe)
  3. Se você está produzindo um executável o cabeçalho PE também inclui um bootstrapper convencional, que é responsável por carregar o CLR (linguagem tempo de execução comum) quando você executa-lo executável.

Agora, quando você executar:

  1. O bootstraper inicializa o CLR (principalmente carregando o mscorlib montagem) e instrui-lo para executar a sua montagem.
  2. O CLR executa a sua entrada principal.
  3. Agora, as aulas têm uma tabela de vetores que mantenha os endereços das funções de método, de modo que quando você chama MyMethod, esta tabela é pesquisado e, em seguida, uma chamada correspondente ao endereço é feita. Após a iniciar todas as entradas para todas as tabelas têm o endereço do compilador JIT.
  4. Quando uma chamada para um de tal método é feita, o JIT é invocado em vez do método real e assume o controle. O JIT, em seguida, compila o código CIL em código de montagem real para a arquitetura apropriada.
  5. Uma vez que o código é compilado o JIT vai para a mesa de método vector e substitui o endereço com a do código compilado, de modo que cada chamada subsequente não invoca o JIT.
  6. Finalmente, as alças JIT a execução para o código compilado.
  7. Se você chamar um outro método que ainda não está sendo compilado e então voltar para 4 ... e assim por diante ...

O JIT é basicamente parte do CLR. O coletor de lixo é outra. Bem onde você colocar interoperabilidade responsabilidades etc é outra questão, e onde eu estou extremamente underqualified ao comentário:)

Eu sei que o segmento é bastante antiga, mas eu pensei que eu poderia colocar na imagem que me fez entender JIT. É a partir do excelente livro CLR via C # por Jeffrey Ritcher . Na foto, os metadados ele está falando é o metadados emitida no cabeçalho de montagem onde todas as informações sobre os tipos no assembly é armazenado:

1) ao compilar o programa .net, código de programa .net é convertido em Intermediate Language (IL) código

2) sobre a execução do programa o código de linguagem intermediária é convertido em código nativo do sistema operacional, como e quando um método é chamado; isso é chamado JIT (Just in Time) compilação.

  1. Common Language Runtime (CLR) é intérprete enquanto Just In Time (JIT) é compilador no .Net Framework.

2.JIT é o compilador interno do .NET que leva código Microsoft Intermediate código do idioma (MSICL) da CLR e executa as instruções de máquina específicas enquanto CLR funciona como um motor de sua tarefa principal é fornecer o código MSICL para JIT para garantir que o código é totalmente compilado conforme especificação da máquina.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top