Langages à objet et machines virtuelles

Le paradigme des langages orientés objets est apparu au fil du temps. Aujourd’hui il est reconnu que les langages à objet présentent des avantages pour programmer de grosses applications grâce à la structure qu’ils apportent. Par langage à objet, on parle généralement de langages à classes (par opposition aux langages à prototype comme Javascript). Le concept de base de l’objet est qu’un objet est instance d’une classe. La classe représente l’ensemble des opérations (les méthodes) que peut effectuer l’objet ainsi qu’une description de ses données (les attributs). L’objet encapsule ses données, qui sont accessibles au monde extérieur à travers les méthodes. Un programme a besoin d’un système d’exécution pour être exécuté et fournir le résultat attendu. On peut classer en trois catégories les systèmes d’exécution : les interpréteurs, les compilateurs et les machines virtuelles. Une machine virtuelle peut être vue comme un système intermédiaire entre l’interpréteur et le compilateur.

Les langages à objet

Historique

Les paradigmes de programmation sont nombreux et sont apparus au fil de l’histoire des langages de programmation. Chaque paradigme s’avère bien sûr plus ou moins efficaces pour modéliser un problème particulier. Mais les styles de programmations sont aussi fluctuants au cours du temps. La programmation fonctionnelle par exemple, a connu ses heures de gloire du temps de Lisp et Scheme puis Smalltalk, ces langages sont ensuite devenus moins populaires avec l’avènement d’autres langages, en particulier orientés objet.

Aujourd’hui la programmation fonctionnelle semble revenir au goût du jour en étant une caractéristique présente dans plusieurs nouveaux langages (Rust, Javascript, Scala).

DÉFINITIONS ET CADRE DE LA THÈSE

L’origine des langages orientés objet remonte aux années 1960. Simula est le premier langage orienté objet, sa première version est disponible en 1967. Ce langage permet de programmer avec des classes, le polymorphisme et l’héritage sont également présents. Smalltalk [Ingalls, 1978,Goldberg and Robson, 1983] est créé ensuite dans les années 1970 et parfait le concept de programmation orientée objets. Les années 1980 voient l’objet se populariser avec plusieurs nouveaux langages : Objective-C (1983), C++ (1983), Eiffel (1984). Parallèlement Lisp s’enrichit d’une couche objet avec CLISP (Common Lisp Object System), ce langage permet également la méta-programmation. Les années 1990 sont ensuite marquées par l’arrivée du langage Java en 1995, qui sera très largement diffusé et utilisé. C♯ est sorti quelques années après, en 2001 et présente des caractéristiques très similaires à Java.

Caractéristiques

Les langages à objet doivent leur popularité aux facilités offertes pour modéliser le monde réel. Le modèle objet introduit en outre de nombreux concepts (classes, héritage, encapsulation…) qui facilitent la réutilisation et la structuration des applications. De manière générale, les langages à objet augmentent la réutilisabilité d’une application car un programme avec des classes est facilement extensible. De plus, le découpage de l’application en classes augmente la modularité, les concepts du programme sont isolés et contenus dans la classe, qui est l’unité de code de ces langages. La compréhension globale de l’application est ainsi facilitée par rapport à un langage non-objet. Le paradigme objet est rapidement explicable par avec une métaphore du monde réel, cet élément a sans doute joué dans l’adoption de ce paradigme. Exemple : On peut décrire de manière abstraite une table et donc en définir la classe comme possédant un plateau, un certain nombre de pieds etc. Un objet représentera une instance, et donc dans ce cas, une table particulière. Cette table aura une couleur, une forme et une hauteur qui lui sont propres. La modélisation est donc partagée en deux : la partie abstraite est contenue dans la classe, la partie concrète est dans les objets instances des classes. L’héritage est aussi une notion facilement explicable, puisque comme noté dans [Ducournau, 2016], le modèle de classification des espèces naturelles peut être représenté par de l’héritage et des objets de façon intuitive.

Définitions et cadre de la thèse

Langages à classe et prototype

Parmi les langages orientés objet, plusieurs variantes existent. Tout d’abord, il faut distinguer les langages à classe des langages à prototype.

Définition 1. Langage à prototype Les classes n’existent pas dans ce système. La réutilisation est effectuée en dérivant un objet d’un autre objet existant.

Définition 2. Langage à classe Les classes sont les entités structurantes du langage. Elles contiennent la définition abstraite de leurs instances, avec les données (attributs) et les opérations (méthodes). Les objets sont ensuite créés à partir des classes et ils possèdent et encapsulent leurs propres données.

La très grande majorité des langages à objet sont basés sur des classes. Parmi les langages à prototype, Javascript est le plus connu aujourd’hui, le premier d’entre eux qui a été largement diffusé étant Self [Ungar and Smith, 1987a], d’autres langages ont existé, par exemple Garnet. Dans le cadre de ce projet, nous travaillerons exclusivement sur les langages à base de classes, qui sont majoritaires parmi les langages à objet.

Typage dans les langages à objet

Le typage statique est un système dans lequel les types sont explicitement écrits dans le programme, la vérification des types est ensuite effectuée à la compilation. Le typage dynamique déporte la problématique de vérification des types à l’exécution. Les programmeurs n’ont pas à les préciser dans le programme, mais cela ne signifie pas que les types n’existent pas ou ne sont pas vérifiés. Parmi les langages à objet, ces deux formes de typage existent avec toutefois une plus grande présence du typage statique. Généralement, un langage ne fait pas cohabiter ces deux systèmes de types. Par contre, un langage typé statiquement peut avoir des vérifications de types à effectuer à l’exécution à travers les casts ou les tests de soustypage. Dans les langages orientés objet en typage dynamique, on peut citer :
— Python (et une machine virtuelle python [Rigo and Pedroni, 2006])
— CLOS [Bobrow et al., 1988]
— Ruby [Flanagan and Matsumoto, 2008]
Les langages à objet en typage statique sont eux plus largement utilisés :
— Java [Gosling, 2000]
— C♯ [Hejlsberg et al., 2003]
— C++ [Stroustrup, 1995]
— OCamL [Leroy et al., 2014]
— Eiffel [Meyer, 2002]
— Rust [Matsakis and Klock II, 2014]
— Ada [Barnes, 2006] .

Nous allons nous concentrer sur les langages en typage statique, comme Java, C♯ et C++, qui n’est pas complètement inféré comme l’est le système de types de OCamL. Dans les langages considérés, un type est une classe.

Table des matières

1 Introduction générale
1.1 Introduction
1.2 Plan de la thèse
2 Langages à objet et machines virtuelles
2.1 Introduction
2.2 Les langages à objet
2.2.1 Historique
2.2.2 Caractéristiques
2.3 Définitions et cadre de la thèse
2.3.1 Langages à classe et prototype
2.3.2 Typage dans les langages à objet
2.3.3 Héritage et langages à objet
2.3.4 Monde ouvert et monde fermé
2.4 Les machines virtuelles
2.4.1 Définitions
2.4.2 Historique
2.4.3 Langage de bytecode
2.4.4 Caractéristiques
2.4.5 Avantages et inconvénients des machines virtuelles
2.4.6 La recherche dans les machines virtuelles .
2.5 Les machines virtuelles pour des langages à objet à typage statique
2.5.1 Java Virtual Machine (JVM)
2.5.2 Le langage Scala
2.5.3 Langage C♯ et CLR
2.6 Implémentation des mécanismes objet
2.6.1 Sous-typage simple
2.6.2 Héritage multiple
2.7 Héritage multiple et machines virtuelles
2.7.1 Héritage multiple et chargement dynamique
2.7.2 Mixins et traits
2.8 Techniques d’implémentation utilisées dans les machines virtuelles
2.8.1 Implémentation des interfaces par IMT
2.8.2 Table à accès direct
2.8.3 Test de sous-typage dans Hotspot
2.8.4 Test de sous-typage basé sur des trits
2.8.5 Hachage parfait
2.9 Récapitulatif
2.10 Conclusion
3 Systèmes d’optimisations adaptatifs
3.1 Introduction et problématique
3.2 Cadre des systèmes étudiés
3.3 Définition et composantes d’un protocole
3.4 Différences avec des compilateurs en monde fermé
3.5 Analyses statiques et dérivés
3.5.1 Analyses statiques en monde fermé
3.5.2 Analyses statiques en monde ouvert
3.6 Récolte d’information
3.6.1 Profilage de l’exécution
3.7 Techniques d’optimisations
3.7.1 Dévirtualisation
3.7.2 Inlining
3.7.3 Customisation et spécialisation
3.8 Techniques de réparation
3.8.1 Gardes
3.8.2 Patch du code
3.8.3 Patch de la pile
3.8.4 Préexistence
3.9 Systèmes d’optimisation complets
3.9.1 JikesRVM
3.9.2 JVM HotSpot
3.10 Conclusion
4 Mesures de performances des protocoles
4.1 Introduction
4.2 Mesures théoriques
4.3 Mesures empiriques
4.3.1 Problématique
4.3.2 Benchmarks
4.4 Mesures de temps
4.4.1 Mesures de temps des programmes compilés statiquement
4.4.2 Mesures de temps et machines virtuelles
4.5 Mesures discrètes
4.5.1 Mesures statiques
4.5.2 Mesures dynamiques
4.5.3 Chargement aléatoire dans [Ducournau and Morandat, 2012]
4.6 Mesures dans les machines virtuelles
4.7 Discussions
4.8 Conclusion
Conclusion générale

Cours gratuitTélécharger le document complet

Télécharger aussi :

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *