Derrière toi Une machine virtuelle! Yann-Gaël Guéhéneuc guehene@emn.fr École des Mines de Nantes, France Object Technology International Inc., Canada D où ça vient? Calculatrice Machine de Turing 1936 λ-calcul et π-calcul 1934 Machine à registres Machine à piles 2/21
Comment? Turing Un ensemble fini d états, d instructions, et un alphabet fini Machine à registre Des registres, un chemin de donnée, un contrôleur Machine à pile Une pile, des opérations, un contrôleur (?) 3/21 Qu est-ce que c est? Une machine virtuelle c est : Un programme qui s interpose entre un programme et un système d exploitation Un interpréteur qui interprète un programme pour un système d exploitation Un compilateur qui compile à la volée un programme pour un système d exploitation 4/21
En bref? Une machine virtuelle c est : Programme Ordinateur Machine virtuelle Système d'exploitation Machine virtuelle Système d'exploitation Programme Ordinateur Une machine virtuelle ce n est pas : Inutile 5/21 Pourquoi? n langages + m systèmes d exploitation = n * m compilateurs n langages + 1 machine virtuelle + m systèmes d exploitation = n compilateurs (+ m machines virtuelles gratuites ) 6/21
Et aujourd hui? La machine virtuelle de Java : Par méthode : Un cadre Par classe : Un paquet Par threads : Une pile Un registre Pour tous les threads : Un tas Une zone «méthodes» Une pile «méthodes natives» 7/21 Et ce n est pas tout? La machine virtuelle de Java : Sandbox Class Loader Garbage collector Security Java Native Interface Java Platform Debug Architecture Java Virtual Machine Profiler Interface 8/21
JNI (1/3) Java Native Interface Interface de la JVM vers l extérieur en C Interface de l extérieur vers la JVM en C 9/21 JNI (2/3) package emn.course.vm; public final class GCD_C { public native int computegcd(int a, int b); static { System.loadLibrary("GCD_C_Impl"); public static void main(string[] args) { GCD_C myjnicalltogcd = new GCD_C(); System.out.println(myJNICallToGCD.computeGCD(6, 18)); 10/21
JNI (3/3) #include "emn_course_vm_gcd_0005fc.h" #include <stdio.h> jint JNICALL Java_emn_course_vm_GCD_1C_computeGCD( JNIEnv * env, jobject obj, jint a, jint b) { if (b == 0) { return a; else { return Java_emn_course_vm_GCD_1C_computeGCD( env, obj, b, a % b); 11/21 JPDA (1/5) Java Platform Debug Architecture Tout pour déboguer / contrôler un programme qui marche dans une machine virtuelle Java Trois niveaux : Java Debug Interface Java Debug Wire Protocol Java Virtual Machine Debug Interface 12/21
JPDA (2/5) JPDA (3/5) 13/21 n Expérimentations : Environnements de développement : IBM Eclipse Borland JBuilder Sun Forte Exemples simples 14/21 7
JPDA (4/5) final VirtualMachineManager vmmanager = Bootstrap.virtualMachineManager(); final LaunchingConnector launchingconnector = vmmanager.defaultconnector(); final Map arguments = launchingconnector.defaultarguments(); final Iterator iterator = arguments.values().iterator(); while (iterator.hasnext()) { final Argument argument = (Argument) iterator.next(); if (argument.name().equals("main")) { argument.setvalue("emn.course.vm.gcd"); final VirtualMachine vm = launchingconnector.launch(arguments); vm.resume(); 15/21 JPDA (5/5) Démo? 16/21
JVMPI (1/4) Java Virtual Machine Profiler Interface Tout pour connaître le profile d exécution d un programme qui marche dans une machine virtuelle Java 17/21 JVMPI (2/4) JNIEXPORT jint JNICALL JVM_OnLoad(JavaVM *jvm, char *options, void *reserved) { fprintf(stderr, "Initializing the profiler for the Course on VMs.\n"); // Get JVMPI interface pointer if (((*jvm)->getenv(jvm, (void **)&jvmpi_interface, JVMPI_VERSION_1)) < 0) { fprintf(stderr, "Initialization error in obtaining JVMPI interface pointer.\n"); return JNI_ERR; // Initialize the JVMPI interface jvmpi_interface->notifyevent = NotifyEvent; // Enable "class load"- and "thread start"-event notification jvmpi_interface->enableevent(jvmpi_event_class_load, NULL); jvmpi_interface->enableevent(jvmpi_event_thread_start, NULL); 18/21 fprintf(stderr, "Initialization done.\n\n"); return JNI_OK;
JVMPI (3/4) 19/21 void NotifyEvent(JVMPI_Event *event) { const char *class_name; const char *thread_name; switch(event->event_type) { case JVMPI_EVENT_CLASS_LOAD: class_name = event->u.class_load.class_name; if (!((class_name[0] == 'j' && class_name[1] == 'a' && class_name[2] == 'v' && class_name[3] == 'a') (class_name[0] == 's' && class_name[1] == 'u' && class_name[2] == 'n'))) { fprintf(stderr, "> Class loaded: %s\n", class_name); break; case JVMPI_EVENT_THREAD_START: thread_name = event->u.thread_start.thread_name; fprintf(stderr, "> Thread started: %s\n", thread_name); break; JVMPI (4/4) Démo? Initializing the profiler for the Course on VMs. Initialization done. 20/21 > Thread started: Signal Dispatcher > Thread started: CompileThread0 > Class loaded: com.sun.rsajca.provider > Class loaded: com.sun.rsajca.provider$1 > Class loaded: emn.course.vm.gcd > Thread started: AWT-EventQueue-0 > Thread started: SunToolkit.PostEventQueue-0 > Thread started: AWT-Windows > Class loaded: emn.course.vm.gcd$1 > Thread started: TimerQueue > Thread started: Thread-0
Et quoi d autre? Lisp / Scheme Pascal Prolog Squeak C# Proof-carrying code Strongly-typed intermediate languages 21/21