Question

  

"Un programme de bytecode est normalement exécuté en analysant les instructions une à la fois. Ce genre d'interprète bytecode est très portable. Certains systèmes, appelés traducteurs dynamiques, ou « juste à temps » compilateurs (JIT), traduire bytecode en langage machine si nécessaire à l'exécution: ce qui rend la machine virtuelle non portable "

.

Une question sur ce paragraphe est que: Après le bytecode ont été traitées, Quelle est la différence entre une instruction et analysable langage machine (ou code machine)?

Était-ce utile?

La solution

JIT est différent d'un interpréteur de pseudo-code binaire.

Considérons la fonction C suivante:

int sum() {
   return 5 + 6;
}

Ce sera compilé le code machine directement. Les instructions précises sur les processeurs x86 disons et ARM seront différentes.

Si nous avons écrit un interprète bytecode de base, il pourrait ressembler à ceci:

for(;;) {
   switch(*currentInstruction++) {
   case OP_PUSHINT:
      *stack++ = nextInt(currentInstruction);
      break;
   case OP_ADD:
      --stack;
      stack[-1].add(*stack);
      break;
   case OP_RETURN:
      return stack[-1];
   }
}

On peut alors interpréter l'ensemble des instructions suivantes:

OP_PUSHINT (5)
OP_PUSHINT (6)
OP_ADD
OP_RETURN

Si vous compilez l'interpréteur de code octet sur x86 ou ARM vous serez alors en mesure d'exécuter le même code d'octet sans faire de plus ré-écriture de l'interprète.

Si vous avez écrit un compilateur JIT vous devez émettre processeur instructions spécifiques (code machine) pour chaque processeur pris en charge, alors que l'interpréteur de code octet se fonde sur le compilateur C pour émettre le processeur des instructions spécifiques.

Autres conseils

Dans un interpréteur de bytecode, le format d'instruction est généralement conçu pour très rapide « l'analyse » à l'aide des opérateurs de décalage et un masque. L'interprète, après « analyse » (je préfère « le décodage ») l'instruction, immédiatement à jour l'état de la machine virtuelle, puis commence à décoder l'instruction suivante. Ainsi, après le bytecode obtient traité dans un interprète , aucun vestige reste.

Dans un compilateur JIT, les octets sont traités dans des unités plus grandes que d'une seule instruction. L'unité minimale est le bloc de base, mais JIT modernes convertira des chemins plus grands en code machine. Ceci est un Traduction étape, et la sortie de l'étape de traduction est code machine. Le bytecode d'origine peut rester en mémoire, mais il ne sert pas à la mise en œuvre, donc il n'y a pas de différence réelle. (Bien qu'il soit typique que le code de la machine pour une machine virtuelle JITted fait des choses différentes à partir du code de la machine émis par un compilateur de code natif.)

Il n'y a pas de différence - compilateur JIT est fait exactement pour cela -. Il produit du code machine qui est exécutée sur le matériel

En fin de compte, tout se résume aux instructions de la machine.

  1. App Native - contient des instructions de la machine qui sont exécutées directement
  2. .
  3. JIT App -. Bytecode est compilé en instructions machine et exécuté
  4. App Traduction -. Bytecode se traduit par une machine virtuelle qui est une application native

Comme vous pouvez le dire, avec # 1, vous avez le moins frais généraux tout avec # 3, vous avez le plus frais généraux. Ainsi, la performance devrait être le plus rapide sur # 1 et tout aussi rapide sur # 2 après les frais généraux de compilation initiale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top