Plan du ours Prodution de ode, langages à héritage multiple Martin Odersky 23 janvier 2007 version 1.2 1 2 3 Prodution de ode, langages à héritage multiple Martin Odersky 1 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 2 de 19 Le shéma de dispathing par table de méthodes virtuelles (VMT) est prédominant dans les situations d héritage simple : Simula, Modula-3, Ada 95, Objet Oberon, Beta... Mais la plupart des langages OO sont plus omplees. Langages ave héritage multiple ou miins : Sala, Eiffel, gbeta, C++... Langages ave sous-typage struturel : Smalltalk, Ceil, Self, Pit... Langages hybrides ave héritage simple et interfaes : Java, Objetive-C... Plusieurs tehniques eistent pour implanter l héritage multiple, les miins ou l héritage hybride : trampolines, tableau de déplaement de lignes (row-displaement tables), antémémoire en ligne (inline ahing). Prodution de ode, langages à héritage multiple Martin Odersky 3 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 4 de 19
Eemple : Des lasses en Drei à héritage multiple lass { val : Int; def (): Int = { return this. def (delta: Int): = { return new (this.() + delta); lass Colored { val : Color; def (): Color = { return this. lass Colored etends Colored, { def (delta: Int): Colored = { return new Colored((), this.() + delta); Prodution de ode, langages à héritage multiple Martin Odersky 5 de 19 L idée est d avoir des points d entrée multiples pour les référenes, un par lasse de base. Chaque point d entrée a un hamp entête () qui pointe vers une table de méthodes virtuelles. Quand on passe d une sous-lasse à une super-lasse on met à jour le pointeur de l objet pour qu il pointe vers le point d entrée orret. La redéfinition d une méthode rend néessaire de se déplaer d un point d entrée au début de l objet englobant. Cela est réalisé par une méthode trampoline qui, une fois appelée, retourne la référene de l objet englobant en soustrayant une valeur onnue du point d entrée. Cette tehnique a été utilisée pour gbeta et C++. Prodution de ode, langages à héritage multiple Martin Odersky 6 de 19 Colored Colored 1 Avantages de la tehnique par trampolines : Des performanes raisonnables même dans le pire des as. Les hamps et les méthodes peuvent être hérités de façon multiple. tramp Colored 2 tramp Désavantages : Suroût des méthodes trampoline. les strutures de données ovariantes ne sont pas supportées : Colored[] <: [] ne peut pas fontionner ar il faudrait alors mettre à jour haque pointeur dans le tableau. Les méthodes trampolines sont, pour Colored 1 : tramp(p) = p, pour Colored 2 : tramp(p) = p - 8. Pour deu variables p: et p: Colored on a : p = p devient p = p + 8, p = p devient p = p.tramp(p). Prodution de ode, langages à héritage multiple Martin Odersky 7 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 8 de 19
Une autre tehnique de dispathing est le tableau de déplaement de lignes (row-displaement table). Le problème du dispathing dynamique est le suivant : Étant donné un ensemble de lasses et de méthodes, trouver le ode orrespondant à une lasse et à une méthode données. Si l on énumère les lasses et les méthodes, ette tâhe se réduit à une opération d indeage dans un tableau bi-dimensionnel : Objet Main equals append main Le tableau de déplaement de lignes devient vite énorme : Une appliation de 500 lasses et 2 000 noms de méthodes uniques rée une table de 1 000 000 d entrées. Ce tableau à deu dimensions est oupé de façon lairsemée ar haque lasse n implante qu un petit sous-ensemble de toutes les méthodes. On peut obtenir une meilleure utilisation de l espae en imbriquant les lignes suessives omme un ensemble de peignes : Prodution de ode, langages à héritage multiple Martin Odersky 9 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 10 de 19 Tableau de déplaement En Java, on peut obtenir une bonne utilisation de l espae de la façon suivante : Indeer le tableau ave les lasses et les interfaes plutôt qu ave les lasses et les méthodes. Une entrée du tableau pointe sur l endroit dans une VMT où la méthode de l interfae est implantée. Cette tehnique a été utilisée dans ertaines implantations très rapides de Java. VMT de Colored interfae Colored interfae Copyable Prodution de ode, langages à héritage multiple Martin Odersky 11 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 12 de 19
Considérations de pipelining Le ode de dispathing pour l appel : obj: I;... obj.meth() est obj.(i.number).meth(). Question : Comment savons-nous que l entrée du tableau est utilisée pour la lasse ourante? Réponse : Nous n avons pas besoin de le savoir, ar Java est statiquement typé! L avantage du dispathing ave tableau à lignes (row table) est sa bonne performane ave le as moyen = au pire des as. Le dispathing par VMT et elui par tableau à lignes introduisent des bulles dans le pipeline. On ne peut aller herher de nouvelles instrutions qu après avoir alulé l adresse dynamique de la méthode. Dans les proesseurs modernes ave des pipelines profonds, ela peut s avérer très oûteu. Un proesseur de type Pentium 4 utilise un pipeline d une profondeur pouvant aller jusqu à 31 stages, sur plusieures instrutions en parallèle : une bulle dans le pipeline oûte très her. C est d ailleurs enore pire ave des proesseurs à mots d instrutions très larges (VLIW) Prodution de ode, langages à héritage multiple Martin Odersky 13 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 14 de 19 Antémémoires En réalité, de nombreu appels vont toujours à la même lasse. On peut améliorer les performanes du dispathing grâe au antémémoires (inline ahing) : Pour haque instrution d appel se rappeler le ode qui a été utilisé à la dernière eéution de ette instrution. Sauter immédiatement vers e ode sans utiliser le dispathing dynamique. Au début du ode ible, tester si l on est dans la bonne lasse. Si e n est pas le as, retourner au shéma de dispathing dynamique lassique, plus lent. Ce shéma permet un gain important si les appels vont toujours à la même lasse... sinon est une grosse perte! Le inline ahing est utilisé pour implanter les appels au méthodes d interfae dans HotSpot : L instrution invoke_interfae a un hamp qui ontient la relative de l entrée de la méthode qui a été invoquée durant la dernière eéution de ette instrution (par rapport au début de la VMT). Quand invoke_interfae est eéutée, il est d abord vérifié qu une entrée pour la méthode appelée se trouve bien à la donnée. Sinon on reherhe linéairement parmi toutes les méthodes de l objet donné une méthode qui orresponde au nom et au type de la méthode appelée. Prodution de ode, langages à héritage multiple Martin Odersky 15 de 19 Prodution de ode, langages à héritage multiple Martin Odersky 16 de 19
Antémémoires polymorphes Compilateurs JIT Le inline ahing est une optimisation tout ou rien : est soit très rapide soit inutile (voir même néfaste). Un ompromis est de garder un tableau des n dernières ibles. Si la ible ourante est dans le tableau, sauter diretement, sinon ontinuer ave le dispathing dynamique et ajouter la nouvelle ible dans le tableau. Si le tableau devient grand : retour au dispathing dynamique. Ce shéma est dérit dans la thèse de Urs Hölzle. Il est utilisé dans les implantations de Self et HotSpot. Avantage : on évite les bulles dans le pipeline : potentiellement de très bonnes performanes, même meilleures que le dispathing simple ave VMT pour l héritage simple. Désavantage : imprévisible : peut être (légèrement) pire que le dispathing ave VMT dans les mauvais as. Prodution de ode, langages à héritage multiple Martin Odersky 17 de 19 L interprétation du byteode Java réduit les performanes. La distribution des lasses Java sous forme de ode natif améliorerait les performanes, mais au pri de la portabilité et de la séurité. (just-in-time) offrent une solution. Un ompilateur JIT ompile le byteode en ode natif, soit au hargement, soit après quelques eéutions du ode. En prinipe le ode ompilé JIT peut être plus rapide que du ode natif ompilé statiquement vu qu il y a plus d informations disponibles à l eéution qu à la ompilation : quelles méthodes sont appelées le plus souvent? ombien de méthodes différentes et appel invoque-t-il? Prodution de ode, langages à héritage multiple Martin Odersky 18 de 19 En pratique le ode ompilé JIT est généralement plus lent que du ode natif ar : le suroût de la ompilation ralentit l eéution, les optimisations des ompilateurs JIT doivent aller vite et sont don moins agressives que les optimisations des ompilateurs de ode natif. Il faut trouver un ompromis sur : ompilateur JIT lent et ode généré rapide ou ompilateur JIT rapide et ode généré lent? quand invoquer le ompilateur JIT? Symante le fait à la première eéution, Inprise à la seonde, HotSpot à la 1 000 e et HotSpot (serveur) à la 10 000 e. Prodution de ode, langages à héritage multiple Martin Odersky 19 de 19