architecture du jeu d'instructions (ISA) de la machine virtuelle Java (JVM), le langage dans lequel Java et d'autres codes sources compatibles JVM sont compilés . Chaque instruction est représentée par un octet , d'où le nom de bytecode , ce qui en fait une forme compacte de données .
Grâce à la nature des machines virtuelles et du bytecode, un programme en bytecode JVM peut être exécuté sur n'importe quelle machine dotée d'une JVM compatible, sans le long processus de compilation à partir du code source.
Le bytecode JVM est utilisé lors de l'exécution , soit interprété par une JVM, soit compilé en code machine via la compilation juste-à-temps (JIT) et exécuté comme une application native.
Comme le bytecode JVM est conçu pour la compatibilité et la sécurité des logiciels multiplateformes , une application en bytecode JVM tend à fonctionner de manière cohérente sur différentes configurations matérielles et logicielles .
programmeur Java n'a pas besoin de comprendre le bytecode de la JVM ni même d'en avoir connaissance. Cependant, comme le suggère la revue IBM developerWorks, « comprendre le bytecode et celui qui est susceptible d'être généré par un compilateur Java aide le programmeur Java de la même manière que la connaissance de l'assembleur aide le programmeur C ou C++ ».Architecture du jeu d'instructions
Le bytecode comprend différents types d'instructions, notamment la manipulation de données, le transfert de contrôle, la création et la manipulation d'objets et l'appel de méthodes, qui font tous partie intégrante du modèle de programmation orienté objet de Java .
The JVM is both a stack machine and a register machine. Each frame for a method call has an "operand stack" and an array of "local variables". The operand stack is used for passing operands to computations and for receiving the return value of a called method, while local variables serve the same purpose as registers and are also used to pass method arguments. The maximum size of the operand stack and local variable array, computed by the compiler, is part of the attributes of each method. Each can be independently sized from 0 to 65535 values, where each value is 32 bits. bytecode is composed of one byte that represents the opcode, along with zero or more bytes for operands.
Of the 256 possible byte-long opcodes, prefixes and/or suffixes referring to the types of operands they operate on. These are as follows:
| Prefix/suffix | Operand type |
|---|---|
i | integer |
l | long |
s | short |
b | byte |
c | character |
f | float |
d | double |
a | reference |
Par exemple, iaddadditionnera deux entiers, tandis daddqu'additionnera deux nombres à virgule flottante double précision. Les instructions const`&&`, `&&` loadet ` store&&` peuvent également prendre un suffixe de la forme ` n` , où n est un nombre compris entre 0 et 3 pour `&& ` et `&& `. La valeur maximale de n pour `&& ` varie selon le type._nloadstoreconst
Les constinstructions empilent une valeur du type spécifié. Par exemple, iconst_5empile un entier (valeur 32 bits) de valeur 5, tandis que dconst_1empile un nombre à virgule flottante double précision (valeur 64 bits) de valeur 1. Il existe également une instruction aconst_null`empile`, qui empile une thisistore_1
Exemple
Considérons le code Java suivant :
- Eclipse compiler for Java (ECJ)
- Jikes, compiles from Java to JVM bytecode (developed by IBM, implemented in C++)
- Espresso, compiles from Java to JVM bytecode (Java 1.0 only)
- GNU Compiler for Java (GCJ), compiles from Java to JVM bytecode; it can also compile to native machine code and was part of the GNU Compiler Collection (GCC) up until version 6.
Some projects provide Java assemblers to enable writing JVM bytecode by hand. Assembly code may be also generated by machine, for example by a compiler targeting a Java virtual machine. Notable Java assemblers include:
- langage d'assemblage de macros pour la machine virtuelle Java. La syntaxe Java est utilisée pour la définition des classes ou des interfaces. Les corps des méthodes sont spécifiés à l'aide d'instructions bytecode.
- Krakatau Bytecode Tools contient actuellement trois outils : un décompilateur et un désassembleur pour les fichiers de classe Java et un assembleur pour créer des fichiers de classe.
- Lilac, un assembleur et désassembleur pour la machine virtuelle Java.
D'autres ont développé des compilateurs, pour différents langages de programmation, afin de cibler la machine virtuelle Java, tels que :
- ColdFusion
- JRuby et Jython sont deux langages de script basés sur Ruby et Python.
- Apache Groovy est un langage généraliste optionnellement typé et dynamique, doté de fonctionnalités de typage statique et de compilation statique.
- Scala , un langage de programmation généraliste à typage statique prenant en charge la programmation orientée objet et fonctionnelle
- JGNAT et AppletMagic compilent le langage Ada en bytecode JVM
- Compilateurs de bytecode C vers Java
- Clojure est un langage fonctionnel, immuable et généraliste de la famille Lisp, qui met fortement l'accent sur la concurrence.
- Kawa , une implémentation du langage Scheme , également un dialecte de Lisp
- MIDletPascal
- Le code JavaFX Script est compilé en bytecode JVM.
- Kotlin , un langage généraliste statiquement typé avec inférence de type
- Le code source Object Pascal est compilé en bytecode JVM à l'aide du compilateur Free Pascal 3.0+.
Exécution
Prise en charge des langues dynamiques
La spécification Java ( JSR ) 292 ( Prise en charge des langages à typage dynamique sur la plateforme Java ) a ajouté une nouvelle invokedynamicinstruction au niveau de la JVM, permettant l'appel de méthodes basé sur la vérification dynamique des types (au lieu de l'instruction existante à vérification statique invokevirtual). La machine Da Vinci est une implémentation prototype de machine virtuelle hébergeant des extensions JVM destinées à prendre en charge les langages dynamiques. Toutes les JVM compatibles avec Java Platform, Standard Edition (JSE) 7 incluent également cet invokedynamicopcode.