1 / 18

Les interprètes et Les Machines Virtuelles

Les interprètes et Les Machines Virtuelles. Abstraction du microprocesseur, les « machines universelles » et leurs implantations sur les systèmes informatiques usuels. Par Gilles Grimaud U niversité des S ciences et T echnologies de L ille http://www.lifl.fr/~grimaud/Cours. Plan.

geordi
Download Presentation

Les interprètes et Les Machines Virtuelles

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Les interprètes et Les Machines Virtuelles Abstraction du microprocesseur, les « machines universelles » et leurs implantations sur les systèmes informatiques usuels. Par Gilles Grimaud Université des Sciences et Technologies de Lille http://www.lifl.fr/~grimaud/Cours

  2. Plan • Abstraire l’utilisation du microprocesseur • Mise en œuvre des interpréteurs • Principe des machines virtuelles • L’exemple des machines virtuelles Java • Technique d’exécution des bytecodes

  3. Abstraire l’utilisation du microprocesseur Objectifs : • Simplifier l’exécution des programmes : • Simplifier l’implantation des algorithmes retenus ; • Réduire le cycle de développement des programmeurs ; • Permettre d’utiliser le langage pour commander la machine. • Mieux maîtriser l’exécution des programmes : • Outils de Debuggage puissants ; • Mécanismes de sécurités avancés (analyse de code, introspection de pile, …). • Définir les programmes indépendamment du matériel : • Permettre l’exécution des mêmes programmes sur des architectures matérielles différentes ; • Augmenter le pouvoir de distribution des applications et de mobilité du code ;

  4. Abstraire l’utilisation du microprocesseur Les 3 techniques , et  d’exécution d’un programme exprimé dans un langage de « haut niveau » reprennent les trois opérations identifiées précédemment (Cours 6) : • Analyse lexicographique ; • Stratégie de conversion du code ; • Sélection des opérations machines à exécuter. Seul le « moment d’exécution » de ces trois opérations change selon la stratégie retenue : Lorsque le programmeurréalise son programme Lorsque le systèmedoit exécuter le programme. (i) (ii) (iii) -  Compilateur  Machine virtuelle (i) (ii) (iii) De l’ordre du possible ! (i) (ii) (iii)  Interpréteur - (i) (ii) (iii) N.B. Nous ne reviendrons pas sur le principe des compilateurs déjà évoquéprécédemment…

  5. Abstraire l’utilisation du microprocesseur Impact sur les performances : • En terme de temps : • Un programme compilé :  • Une machine virtuelle : (iii) + k. • Un interpréteur = (i) + (ii) + (iii) + k. 2. En terme d’espace (valeurs à titre indicatif) : Pour un source C ou Java de 100 Ko ont constate : • Une représentation arborescente (compacte) du source de 75 Ko • Une représentation « bytecodée » (Java) de 35 Ko • Un binaire SISC de 46 Ko de code exécutable. • Un binaire RISC de 69 Ko de code exécutable. Facteur d’erreur Taille du code

  6. les interpréteurs Un code interprété est un code pour lequel aucune opération de traitement du source n’est effectuée avant l’exécution. Intérêt : • Interface Homme/Machine minimale ; • Cycle de développement minimaliste ; • Génération automatique simplifiée de code… Exemple : • Interpréteur de commande (Shell) ; • JavaScript, VBScript, CorbaScript ; • Lisp, …

  7. Mise en œuvre des interpréteurs Un interpréteur est un programme (natif) qui réalise les opérations (i), (ii) et (iii). Produire un arbre d’analyse à partir du code source à exécuter. Exemple : « a = b + 3 ; » Entrée de l’arbre Opération « = » Variable « a » Opération « + » Variable « b » Constante « 3 »

  8. Mise en œuvre des interpréteurs « Evaluer » l’arbre : parcourt en profondeur d’abord, empiler les résultats d’évaluation de chaque nœud de l’arbre, utiliser un dictionnaire pour les variables. Dictionnaire avant : a 9 Entrée de l’arbre b 2 Trace de la pile d’exécution Opération « = »       3 Variable « a » Opération « + » 5   b b a a a a Dictionnaire après : Variable « b » Constante « 3 »   a 5 b 2

  9. Les Machines Virtuelles • « Compiler le code source » : En fait exécuter l’opération (i) et (ii) de transformation de code. (ii)  définir une stratégie de génération de code (pour Java : machine à pile). 2. Ensuite « évaluer » le code binaire virtuel : C’est-à-dire, choisir et exécuter pour chaque opérations virtuelle une séquence d’opérations natives équivalentes. Intérêt : • Détecter en avance (compilation) des erreurs évidentes ; • Réduire les temps de chargement de l’exécutable ; • Assurer la portabilité des codes natifs. Exemple :les machines virtuelles Java, Small talk, prolog, …

  10. L’exemple des machines virtuelles Java Les outils du langage Java Compilateur de source java Code source java- fichier.java - javac test.java Code binaire java- fichier.class - javap –c test.class Phase de développement Phase d’exécution Programme d’inspectiondu code compilé (équivalent objdump) Exécution du code java test.class Programme d’évaluation du codebinaire (machine virtuelle).

  11. L’exemple des machines virtuelles Java 200 bytecodes (codes binaires java), 5 Catégories d’opérations élémentaires: 3- Manipulation de la pile :iload_x, iload, istore_x, istore,aload_x, aload, astore_x, astore, iconst_x, bipush, sipush, ldc, dup, dup2, swap, swap2, pop, pop2 4- Manipulation des objets :new, newarray, anewarray, multianewarray, arraylength,aaload, iaload, aastore, iastore, getfield, putfield,getstatic, putstatic. 2- Opérations arithmétiques et logiques :iand, ior, ixor, ishl, ishr, icmp, tst, iadd, isub, imul, idiv, irem, fadd, fsub, fmul, fdiv, frem, … 5- Appels/Retour de méthodes :invokestatic, invokevirtual, invokespecial, invokeinterface, return, ireturn, areturn, freturn, dreturn, lreturn. 3- Opérations de flot de contrôle :goto, ifeq, ifne, ifnull, …tableswitch, lookupswitch, monitorenter, monitorexit, throw, jsr, ret.

  12. Technique d’exécution des bytecodes Interpréteurs de bytecode : 1 bytecode = 1 octet (valeur de 0..255) + Éventuellement x octets de paramètre Exécuter un bytecode : • Lire l’octet à partir du pointeur de programme courant pp, et incrémenter pp ; • brancher à la séquence d’opérations machines (réelles) à exécuter, et exécuter ces opérations ; • Itérer au point 1.

  13. Technique d’exécution des bytecodes Exemples d’interpréteurs : Interpréteur « switch-case » : /* boucle d’interprétation */ while(!stop) { switch (*pp++) { case 0 : break; /* nop */ case 1 : /* aconst_null */ *tos++ = (int) NULL; break; case 2 : /* iconst_m1 */ *tos++ = -1; break; case 3 : /* iconst_0 */ ... } } Interpréteur « table de fonctions » : fctbytecode fct_table[201] = {nop,aconst_null,iconst_m1,…}; ... /* boucle d’interprétation */ while(!stop) { fct_table[*pp++](); } ... void nop() {} void aconst_null() {*tos++=NULL ; } void iconst_m1() {*tos++=-1; }

  14. Technique d’exécution des bytecodes Interpréteurs optimisés de bytecode : Trace d’exécution en code machine du bytecode java aconst_null : (case d’un interprète « switch-case ») 001 - L13: movzbl (%edi),%eax 002 - incl %edi 003 - cmpl $202,%eax 004 - ja L11 005 - jmp *L29(,%eax,4) 006 - L16: movl $0,(%esi) 007 - addl $4,%esi 008 - jmp L11 009 - L11: testl %edi,%edi 010 - je L13 Sélection Switch (*pp++) { case 1: /* aconst_null */ *tos++ = NULL; break ; Exécution Boucle while(!stop) {

  15. Technique d’exécution des bytecodes Interpréteurs optimisés de bytecode : Solution  Interpréteur « table de labels » (non C ANSI…) : { static const labelbytecode lbltable[201] = { nop, aconst_null, iconst_m1, ...} ; ... /* premier appel d’interprétation */ goto lbltable[*pp++] ; /* implémentation de nop */ nop: goto lbltable[*pp++]; /* implémentation de aconst_null */ aconst_null: *tos++=NULL ; goto lbltable[*pp++]; /* implémentation de iconst_m1 */ iconst_m1: *tos++=-1; goto lbltable[*pp++]; ... } Trace d’exécution de aconst_null : 001 – L16: movl $0,(%esi) 002 - incl %edi 003 - addl $4,%esi 004 - movzbl (%edi),%eax 005 - jmp *L29(,%eax,4)

  16. Technique d’exécution des bytecodes Direct threading de bytecode : Pour accélérer encore l’exécution, lors du chargement, remplacer les bytecodes par la séquence de code machine équivalente… Séquence des bytecodes dans le .class Desassemblage du code stocké en mémoire aconst_null astore_1 aconst_null 001 – movl $0,(%esi) 002 - addl $4,%esi 003 – movl (%esi),eax 004 – movl $4(ebp),eax 005 – subl 4,%esi 006 – movl $0,(%esi) 007 - addl $4,%esi

  17. Technique d’exécution des bytecodes Compilateur à la volée de bytecode : Lors du chargement du bytecode dans la JVM, Ré-appliquer (ii) et (iii) sur le bytecode, • Convertir du code à pile en code à registre : Bytecode java : .method int add(int a,int b) .locals 3.stack 2 iload_0 iload_1 iadd istore_2 iload_2 ireturn Code compilé : mov %eax,%ecx add %ebx,%ecx mov %ecx,%eax rts stack Frame locals %ebx Forme optimisée : add %ebx,%eax rts b a %eax

  18. Technique d’exécution des bytecodes Couplage Interpréteur / Compilateur à la volée : • Compilation = traitement lourd  démarrage long Idée : Paralléliser interprétation et génération de code natif. Méthode par méthode : • 1 méthode = 1 bloc de bytecode + 1 bloc (optionnel) de code natif ; • marquage des appels par l’interpréteur ; • Une thread de compilation à la volée qui compile la méthode la plus appelée ; • L’interprète exécute les bytecodes d’appel de méthode en appelant le code natif s’il existe, ou en interprétant le bytecode de la méthode appelée sinon.

More Related