Java embarqué Module I500 de L3 Benoît Miramond Problématique Quel rapport entre Java et l’architecture ? Java travail sur un modèle d’exécutif différent des langages compilés => Étude des modèles exécutif au cours 4 Le bytecode java se base sur un jeu d’instruction à pile => Modèle différent des architectures étudiés jusqu’ici Il est possible d’implanter la JVM en matériel : les processeurs Java pour l’embarqué Plan du chapitre Spécification de la machine virtuelle Java (JVM) I. I. II. II. III. IV. Specification Java dans l’embarqué Principe de la pile Architecture picoJava contrôleur micro programmé a) Les types de la JVM Numeric Types Integral types Byte Short Int Long Char Floating point types Float Double 8bits signés 16bits signés 32 bits signés 64 bits signés 16 bits non­signés UNICODE 32 bits IEEE­754 64 bits IEEE­754 Les types primitifs de la JVM Boolean type Int Type Boolean array : instruction newarray Manipulé par les instructions de tableaux de bytes : baload bastore ReturnAddress type Pointeurs sur des opcodes d’instruction JVM Les types références de la JVM Reference types Class types Array types Interface types Special value : null b) Sections mémoires en général Pour les programmes compilés, la mémoire est décomposée en trois parties Le tas est la zone dans laquelle s'effectuent l'allocation et la désallocation de la mémoire de façon aléatoire (malloc). La mémoire globale est l'endroit où sont placées les variables globales. Elles sont allouées lors du démarrage du programme et y restent jusqu'à la fin. La pile est l’espace mémoire réservée à l’exécution du programme par l’intermédiaire de ses routines. Lorsqu'on appelle une routine, ses paramètres et le type retourné sont placés sur la pile, de même que les variables locales. A la fin de l’exécution de la routine la pile est libérée. b) Sections mémoires de la JVM PC Compteur de programme Nb : 1/thread Type : returnaddress Heap Données dynamiques et instances de classes Nb : zone partagée Taille : fixe/variable Sections mémoires de la JVM Method Area Code des méthodes (.text) et Constant Pool Nb : zone partagée Emplacement : heap Constant pool Constantes de classes (~table des symbôle) Emplacement : method area Types : primitifs Sections mémoires de la JVM Stack Nb : 1/ thread Frames Nb : 1/method Local variables (LV) Adressé par index (ref à this par LV[0]) Operand stack (SP) Reference on Constante Pool (CPP) Une pile par routine (méthode, fonction, procédure) int ma_var_glob; //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ int main (){ int main_var = 2; ma_var_glob = f1 (main_var); return f2(ma_var_glob); } //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ int f1 (int p1){ … } //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ int f2 (int p2){ … f3(); … } //­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ int f3 (){ … } Pile f1 Pile main Pile main Pile main Pile f3 Pile f2 Pile f2 Pile f2 Pile main Pile main Pile main Pile main c) Exemple de code class fibonnaci { static void calcsequence(){ long fibonum = 1; long a = 1; long b = 1; for ( ; ; ) { fibonum = a+b; a = b; b = fibonum; } } } Lconst_1; Lstore_0; // a Lconst_1; Lstore_2; // b Lconst_1; Lstore_4; // fibonum Lload_0; Lload_2; Ladd; Lstore_4; Lload_2; Lstore_0; Lload_4; Lstore_2; goto 7; d) Jeu d’instruction de la JVM (presque) toutes les instructions sont typées L’Opcode est préfixé par le type des données : I integer L long S short C Char F Float D Double A Reference En fait, S, C et les booléens sont manipulés comme des I Dans ce cours, limitation aux types I Instructions de chargement/rangement Iload, lload, fload, dload, aload Chargement d’une variable locale sur la pile Iload my_var Istore, … Bipush Rangement du haut de pile dans une variable locale Chargement d’une constante sur le haut de pile Suite du jeu d’instruction Instructions arithmétiques et logiques (sur I) Iadd, ISub, Imul, Idiv, Irem (reste), Ineg, Ishl, Ishr, ior, iand, ixor, iinc Instructions de conversion de type Int to long, float or double : i2l, i2f et i2d Instructions de création/manipulation d’objets Création d’une instance de classe : new Création d’un tableau : newarray Accès à un champ de classe : getfield, putfield… Chargement d’un tableau sur la pile : iaload/iastore Taille d’un tableau : arraylength Suite du jeu d’instruction Instructions de gestion de la pile Instructions de contrôle de flux athrow Divers Invokevirtual : méthode d’instance, InvokeInterface : méthode d’interface, Invokespecial : méthode d’instance (private, superclass…) Invokestatic : méthode de classe, Ireturn. Instructions de lancement d’exceptions Branchements conditionnels : ifeq, iflt, ifle, ifne… Branchements incondionnels : goto, jsr, ret… Instructions d’invocation/de retour de méthodes Pop, push, swap, … monitorenter, monitorexit e) Boucle principale de l’interpréteur do { fetch an opcode; if (operands) fetch operands; execute the action of the opcode; } while(no more instructions); f) Informations quantitatives Le codop d’une instruction de la JVM prend 8 bits Chaque opérande supplémentaire tient également sur 8 bits La majorité des instructions utilisées travaillant sans opérande, la taille moyenne d’une instruction JVM est 1,8 octet 2) Java dans l’embarqué Modèles de déploiement et d’exécution Java compilé en binaire natif : Compilation éclair Compilation sur le serveur des classes au moment de la requête en fonction de l’architecture cible JIT : Just In Time Edition de liens statique Édition de liens dynamique Traduction à la volée du bytecode en langage machine Taille du code multiplié par 3 ROMlet : édition de liens statique ROMlet + édition de liens dynamique Processeur Java (JavaChip) 1996 Sun définit l’architecture (pas le circuit) d’un processeur Java : PicoJava II 1997 Sun conçoit un circuit implantant cette architecture : microJava701 Exécute du code Java Exécute également du code C/C++ Chemin de données à 6 étages de pipeline 200 Mhz 16 Ko de cache instruction et de données Unité flottante 32 bits Big/little endian Accélération de l’exécution Java : de 3 à 5 fois plus rapide qu’un pentium II 3 styles architecturaux Machines à chargement/rangement (banc de registre) Machine à accumulateur Machine à pile Processeurs Java Processeurs basés sur une architecture à pile Nombre d’instruction supérieur de 30% à une architecture à registres La nature objet du langage provoque un grand nombre de changements de contextes Système embarqué utilisant une implantation microJava701 de Sun Pourquoi un processeur Java ? En environnement embarqué : L’interprétation est trop longue pour des applications temps réel, La taille de l’interpréteur de tient pas sur des systèmes à faible capacité mémoire,