« Fonctionnement d'un ordinateur/Les architectures à capacités » : différence entre les versions

Contenu supprimé Contenu ajouté
m typo
Ligne 5 :
Sur les architectures à capacité, la notion même d'adresses mémoire n'existe pas (ou presque). À la place, chaque donnée manipulée par le processeur est stockée dans un '''objet''', une sorte de conteneur générique placé quelque part dans la mémoire, sans que l'on ait de moyen de savoir où. Cet objet peut être absolument n'importe quoi : cela peut être un objet spécifié par le programmeur, ou des objets prédéfinis lors de la fabrication du processeur. Par exemple, on peut considérer chaque périphérique comme un objet, auquel on a défini des méthodes bien particulières qui permettront de communiquer avec celui-ci ou de le commander. Sur d'autres architectures, chaque programme en cours d’exécution est considéré comme un objet, avec des méthodes permettant d'agir sur son état. On peut ainsi stopper l’exécution d'un programme via des méthodes adaptées, par exemple. Mais ce qui va nous permettre d'adapter des langages de programmation orientés objet sur de telles architectures, c'est la possibilité de créer soi-même des objets non définis lors de la fabrication du processeur.
 
Au lieu d’utiliser des adresses mémoire et autres mécanismes divers et variés, chaque objet se voit attribuer un '''identifiant''' unique (deux objets ne peuvent avoir le même identifiant), qui ne change pas au cours du temps. L'identifiant est définitdéfini lors de la création de l'objet et ne peut être réutilisé pour un autre objet que lorsque l'objet possédant cet identifiant est détruit. Dans les grandes lignes, on peut voir cet identifiant comme une sorte d'adresse virtuelle, qui permet de localiser l'objet mais peut correspondre à une adresse physique totalement différente. De plus, chaque objet est associée à des '''autorisations d'accès'''. Par exemple, le code d'un système d'exploitation aura accès en écriture à certains objets critiques, qui contiennent des paramètres de sécurité critique, mais les autres programmes n'y auront accès qu'en lecture (voire pas du tout). Ces droits d'accès sont rassemblés dans que l'on appelle une '''capacité'''. Celles-ci décrivent les droits d'accès, l'identifiant et éventuellement le type de la donnée. Le type peut correspondre à des types prédéfinis, mais peut correspondre à des types définis par le programmeur.
 
Les instructions de lecture et écriture prennent comme argument un identifiant et une capacité. Pour avoir accès à un identifiant, le programme doit fournir automatiquement la capacité qui va avec et la charger dans des registres spécialisés. Les capacités sont mémorisées dans la mémoire RAM et sont regroupés au même endroit. Dans le détail, chaque programme ou fonction a accès à une '''liste de capacités''' en mémoire RAM. Les instructions qui manipulent les registres de capacités ne peuvent pas, par construction, augmenter les droits d'accès d'une capacité : ils peuvent retirer des droits, pas en ajouter. Ce mécanisme interdit donc à tout sous-programme ou programme de modifier un objet qui n'est pas dans sa liste de capacité. Avec ce genre de mécanismes, il devient difficile d’exécuter certains types d'attaques, ce qui est un gage de sureté de fonctionnement indéniable. Du moins, c'est la théorie, car tout repose sur l'intégrité des listes de capacité. Si on peut modifier celles-ci, alors il devient facile de pouvoir accéder à des objets auxquels on n’aurait pas eu droit.
Ligne 17 :
==Premier exemple : le processeur Rekursiv==
 
Nous allons commencer par aborder le processeur Rekursiv. Ne soyez pas perturbé par son nom : il ne s'agit pas d'une coïncidence, comme on le verra plus tard. Ce processeur fut inventé par la compagnie Linn Product, un fabricant de matériel Hi-Fi, qui voulait améliorer ses chaînes de production automatisées. Celles-ci fonctionnaient avec un ordinateur DEC VAX assez correct pour l'époque. Cette compagnie avait lancé un grand projet de rajeunissement de sa chaîne de production. Au tout début, le projet consistait simplement à créer de nouveaux outils logiciels pour faciliter le fonctionnement de la chaîne de production. Au cours de ce projet, un langage de programmation orienté objet, le Lingo, fut créé dans ce but. Mais les programmes créés dans ce langage fonctionnaient vraiment lentement sur les DEC VAX de l'entreprise. L'entreprise, qui n'avait pas hésité à créer un nouveau langage de programmation pour ce projet, prit ce problème de performances à bras -le -corps et décida carrément d'inventer un nouveau processeur spécialement adapté à Lingo. Ainsi naquit le processeur Rekursiv, premier processeur orienté objet de son genre. Rekursiv était au départ prévu pour être utilisé sur des stations de travail Sun 3. Mais malgré ses nombreuses qualités, Rekursiv ne s'est pas beaucoup vendu dans le monde : à peine 20 exemplaires furent vendus. La majorité des acheteurs étaient des chercheurs en architecture des ordinateurs, et rares furent les entreprises qui achetèrent des processeurs Rekursiv. Il faut dire que ce processeur était relativement spécialisé et difficile à utiliser, sans compter que d'autres processeurs concurrents firent leur apparition, comme l'Intel 432. Ce processeur fut donc un échec commercial retentissant, malgré une réussite technique indéniable.
 
Vu de loin, ce processeur ressemble à un processeur tout à fait normal, découpé en quatre grands circuits principaux bien connus :
Ligne 34 :
Certaines des instructions du processeur étaient adaptées au paradigme objet et permettaient de gérer plus simplement les diverses fonctionnalités orientées objet au niveau du matériel. Ces instructions étaient toutes micro-codées, bien évidemment. Par exemple, il existait des instructions CREATE, chacune capable de créer un objet d'une certaine classe. Cette instruction n'était autre qu'un constructeur pour un certain type d'objet. Elle avait besoin de certaines données pour fonctionner (sa taille, son type et les valeurs initiales de ses attributs) qui étaient passés par la pile vue ci-dessus. Il existait aussi des instructions de transfert de messages entre objets (comme SEND), des instructions pour accéder à un champ d'un objet localisé sur la pile (GET), pour modifier un champ dans l'objet (PUT), et bien pire encore. On peut signaler que ces instructions ne pouvaient opérer que sur certains types d'objets : certaines instructions ne pouvaient ainsi manipuler que des objets d'une certaine classe et pas d'une autre.
 
Mais ce qui fait que Rekursiv était un processeur orienté objet ne vient pas seulement de son jeu d'instructions : le principal intérêt de Rekursiv tient dans son unité chargée de gérer la mémoire. Les capacités de ce processeur étaitétaient codées sur 40 bits. Objekt, la MMU, se chargeait de convertir les capacités en adresses mémoires de façon transparente pour les instructions. La MMU stockait diverses informations sur chaque objet : ainsi, la MMU pouvait retrouver l'adresse mémoire de l'objet, son type, et sa taille à partir de l'identifiant. Ces informations étaient stockées dans la mémoire, dans une table segments dédiée. Du fait de l'usage de la segmentation, un objet gardait en permanence la même capacité. On pouvait déplacer l'objet dans la mémoire, son identifiant restait le même (alors que son adresse mémoire changeait). De même, la MMU pouvait décider de déplacer un objet sur le disque dur sans que le programme ne s'en aperçoive.
 
Objekt implémentait un Garbage Collector matériel assez simple, mais suffisamment efficace. Pour rappel, un garbage collector, ou ramasse-miettes, est un programme ou un système matériel qui se charge de supprimer de la mémoire les objets ou données dont on n'a plus besoin. Dans certains langages de programmation comme le C ou le C++ , on est obligé de libérer la mémoire à la main. Ce n'est pas le cas pour certains langages orientés objet, comme JAVA ou Lingo : un garbage collector permet de gérer la mémoire automatiquement, sans demander au programmeur de se fatiguer à le faire lui-même (du moins, en théorie). Ce garbage collector avait souvent besoin de déplacer des objets pour faire un peu de place en mémoire, et compacter les objets ensemble, pour faire de la place. Le fait que les objets soient manipulés avec une capacité facilitait énormément le travail du garbage collector matériel.