La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Environnements d'exécution

Présentations similaires


Présentation au sujet: "Environnements d'exécution"— Transcription de la présentation:

1 Environnements d'exécution
Notions de base Spécificités des langages sources Organisation de la mémoire Stratégies d'allocation mémoire Accès aux noms non locaux Passage de paramètres

2 Objectifs Décrire la relation entre le programme source et l'exécution
Exemple de notion statique : les noms des variables (font partie du programme source) Exemple de notion dynamique : les adresses des variables (existent pendant l'exécution) Décrire le moteur d'exécution Le code que le système d'exploitation lance pour exécuter le programme compilé Langages C, Java, Pascal, Lisp, Fortran

3 Notions de base (1/2) Procédures ou fonctions
Définies par l'association d'un identificateur, le nom, et d'une instruction, le corps Parfois on dit fonction quand elle renvoie une valeur et procédure sinon ; nous ne ferons pas la différence Paramètres formels Dans la définition de la fonction Paramètres effectifs Dans un appel de la fonction Activation d'une fonction Période qui va de l'appel d'une fonction (avec éventuellement des paramètres réels) à son retour

4 Exemple program sort(input, output) ;
var a : array[0..10] of integer ; procedure readarray ; var i : integer ; begin for i := 1 to 9 do read(a[i]) end ; function partition(y, z : integer) : integer ; begin ... end ; procedure quicksort(m, n : integer) ; begin if (n>m) then begin i := partition (m, n) ; quicksort(m, i - 1) ; quicksort (i + 1, n)

5 Exemple end end ; begin a[0] := - 9999 ; a[10] := 9999 ; readarray ;
quicksort(1, 9) end.

6 Notions de base (2/2) Fonctions récursives
Fonction dont une activation peut commencer alors qu'une autre est en cours Arbre d'exécution Les noeuds sont les activations des fonctions avec leurs paramètres Chaque fils d'un noeud correspond à un appel Pile d'exécution La pile des activations en cours à un instant donné Portée d'une déclaration Noms locaux, noms globaux

7 Arbre d'exécution sort quicksort(1, 9) readarray partition(1, 9)

8 Pile d'exécution ... ... sort quicksort(1, 9) readarray
partition(1, 9) quicksort(1, 3) quicksort(5, 9) partition(1,3) partition(5, 9) quicksort(1, 0) quicksort(5, 5) ... ... sort quicksort(1, 9) quicksort(1, 3) fond de pile sommet de pile

9 Notions statiques et dynamiques
Exemple : passage d'un nom de variable à une valeur liaison état nom adresse valeur Si l'environnement associe une occurrence du nom x à l'adresse s, on dit que x est lié à s Un nom peut être lié à plusieurs adresses Une occurrence d'un nom peut être liée à plusieurs adresses (fonction récursive) Une adresse peut contenir plusieurs valeurs successivement

10 Notions statiques et dynamiques
statique dynamique connu à la compilation dépend de chaque exécution définition d'une fonction activations d'une fonction déclaration d'un nom liaisons d'un nom portée d'une déclaration durée de vie d'une liaison

11 Spécificités des langages
L'organisation d'un compilateur dépend des réponses à des questions sur le langage source Y a-t-il des fonctions récursives ? Comment sont traités les noms locaux au retour des fonctions ? Une fonction peut-elle utiliser des noms non locaux ? Comment sont passés les paramètres ? Les fonctions peuvent-elles être passées en paramètre ? être renvoyées comme valeur ? L'allocation de mémoire peut-elle être dynamique ? La libération doit-elle être explicite ?

12 Organisation de la mémoire
Zone utilisée en mémoire pour l'exécution d'un programme Code exécutable (taille statique) Données statiques : dont les adresses sont compilées dans le code Pile d'exécution Le tas est l'emplacement de toutes les autres informations : en C, la mémoire allouée dynamiquement Les adresses dans la pile sont des adresses relatives (offset) par rapport au sommet de la pile code données statiques pile tas

13 Enregistrements d'activation
Zone de mémoire empilée à l'appel d'une fonction et dépilée au retour fond de pile Lien de contrôle : pointe sur l'enregistrement d'activation appelant Lien d'accès : accès aux variables non locales Etat machine : valeurs des registres au moment de l'appel Zone temporaire : pour le calcul des expressions valeur renvoyée paramètres effectifs lien de contrôle lien d'accès (en Pascal) sauvegarde de l'état de la machine variables locales zone temporaire sommet de pile

14 Disposition des données locales
Adresses calculées à la compilation Unité minimale d'adressage L'octet (byte) Pour certaines opérations : le mot machine, souvent 4 octets Espace laissé vide : remplissage (padding) Placement d'un objet Octets consécutifs (la taille dépend du type) L'adresse est celle du premier octet Pendant l'analyse des déclarations Adresses relatives Par rapport à un point de référence dans l'enregistrement d'activation

15 Exemple La taille de chaque type C dépend de la machine machine type
char short int long float taille (bits) 8 16 32 alignement (bits) taille 24 48 64 alignement 1 2 Alignement : sur la machine 1, si un char est suivi d'un short, on perd 1 octet Taille d'un pointeur : sur la machine 2, 24 bits pour le mot et 6 pour 1 bit parmi 64, donc 30 bits

16 Allocation statique La stratégie d'allocation mémoire la plus simple
Toutes les liaisons sont permanentes pendant toute l'exécution Les valeurs des noms locaux persistent d'un appel au suivant Les adresses des données sont statiques L'emplacement des enregistrements d'activation est statique Limitations La taille de toutes les données est statique La récursivité est interdite La création dynamique de structures de données est interdite

17 Exemple Un programme en Fortran qui
- lit une ligne et la copie dans un tampon BUFFER - copie BUFFER dans BUF jusqu'à rencontrer un espace, puis affiche BUF (programme principal) Exemple entrée : demain matin sortie : demain La fonction PRDUCE - lit la ligne et la copie dans BUFFER (premier appel) - puis lit dans BUFFER un caractère par appel Le programme principal écrit dans BUF puis affiche BUF Attention au choc culturel...

18 Exemple PROGRAM CNSUME CHARACTER * 50 BUF INTEGER NEXT
CHARACTER C, PRDUCE DATA NEXT /1/, BUF /' '/ 6 C = PRDUCE() BUF(NEXT:NEXT) = C NEXT = NEXT + 1 IF ( C .NE. ' ' ) GOTO 6 WRITE (*, '(A)') BUF END

19 CHARACTER FUNCTION PRDUCE()
CHARACTER * 80 BUFFER INTEGER NEXT SAVE BUFFER, NEXT DATA NEXT /81/ IF ( NEXT .GT. 80 ) THEN READ (*, '(A)') BUFFER NEXT = 1 END IF PRDUCE = BUFFER(NEXT:NEXT) NEXT = NEXT+1 END

20 L'instruction SAVE permet à PRDUCE de retrouver les valeurs de BUFFER et NEXT d'un appel à l'autre
code de CNSUME code de PRDUCE enregistrement d'activation de CNSUME : BUF NEXT C enregistrement d'activation de PRDUCE : BUFFER code données statiques

21 Allocation en pile Les enregistrements d'activation sont empilés à l'appel de la fonction et dépilés au retour Les valeurs locales sont perdues Séquence d'appel réserve et remplit un enregistrement d'activation Séquence de retour restaure l'état de la machine avant l'appel pour reprendre l'exécution où elle en était

22 sauvegarde de l'état machine données locales temporaires
valeur renvoyée paramètres lien d'accès sauvegarde de l'état machine données locales temporaires enregistrement d'activation de l'appelant lien de contrôle à la charge de l'appelant valeur renvoyée paramètres lien d'accès sauvegarde de l'état machine données locales temporaires enregistrement d'activation de l'appelé lien de contrôle sommet de pile

23 Séquences d'appel et de retour
Séquence d'appel L'appelant évalue les paramètres Il enregistre l'adresse de retour et la valeur du sommet de pile dans l'enregistrement d'activation de l'appelé Il incrémente le sommet de pile L'appelé sauvegarde les valeurs des registres Il initialise ses données locales Séquence de retour L'appelé place la valeur à renvoyer Il restaure le sommet de pile et les autres registres et saute à l'adresse de retour L'appelant copie la valeur renvoyée

24 Allocation en pile Données de taille variable
Les données de taille variable sont placées sur la pile au-dessus de l'enregistrement d'activation Leur adresse relative n'est pas connue à la compilation L'enregistrement d'activation contient des pointeurs vers ces données Les adresses relatives de ces pointeurs sont connues à la compilation On utilise un 2e pointeur de sommet de pile qui tient compte des données de taille variable (sommet)

25 sauvegarde de l'état machine
lien d'accès sauvegarde de l'état machine lien de contrôle enregistrement d'activation de p pointeur sur A pointeur sur B tableau A tableaux de p tableau B lien d'accès sauvegarde de l'état machine données locales temporaires lien de contrôle enregistrement d'activation de q sommet de pile tableau A tableaux de q sommet

26 Allocation en pile Données de taille variable Au retour de q,
la nouvelle valeur de Sommet est restaurée à partir de SommetPile en tenant compte de la taille des champs de sauvegarde, liens, paramètres et valeur de retour la nouvelle valeur de SommetPile est la valeur du lien de contrôle

27 Accès aux noms non locaux
Dépend des règles de portée des variables dans le langage source Les règles qui relient les occurrences des variables à leurs déclarations Portée statique ou lexicale C, Java, Pascal, Ada Portée déterminée par le texte source du programme Portée dynamique Lisp, APL, Snobol Portée déterminée par les activations en cours

28 Structure de blocs Bloc --> { Déclarations Instructions }
Les instructions peuvent contenir des blocs Une fonction peut contenir plusieurs blocs Portée statique La portée d'une déclaration faite dans B est incluse dans B Si un nom x n'est pas déclaré dans B (non local à B), une occurrence de x dans B est liée à la déclaration de x dans le plus petit bloc B' tel que - x est déclaré dans B' - B' contient B

29 Exemple B0 B1 B2 B3 main() { int a = 0 ; int b = 0 ; int b = 1 ;
printf("%d %d", a, b) ; } int b = 3 ; B0 B1 B2 B3

30 Portée statique Réalisation : deux méthodes Allocation en pile
On considère chaque bloc comme une fonction sans paramètres ni valeur de retour Allocation globale On regroupe toutes les variables déclarées dans les blocs de la fonction On peut lier à une même adresse deux variables dont les portées sont disjointes (a de B2 et b de B3)

31 Portée statique sans fonctions emboîtées
Les noms sont de deux sortes : - locaux à une fonction - globaux, déclarés hors des fonctions Exemple : le langage C Les noms globaux sont alloués de façon statique Les noms locaux sont en pile, accessibles à partir du pointeur de sommet de pile Pas besoin de lien d'accès

32 Fonctions passées en paramètre
Avec la portée statique sans fonctions emboîtées, on peut facilement passer une fonction en paramètre ou la renvoyer comme résultat #include <stdio.h> int m ; int f(int n) { return m + n ; } int g(int n) { return m * n ; } int b(int (*h)(int)) { printf("%\n", h(2)) ; } int main(void) { m = 0 ; b(f) ; b(g) ; }

33 Portée statique avec fonctions emboîtées (1/6)
En Pascal, on peut déclarer une fonction à l'intérieur d'une autre Les emboîtements de fonctions forment un arbre statique sort readarray exchange(i, j) quicksort(m, n) Profondeur d'emboîtement 1 pour le programme principal On ajoute 1 pour chaque imbrication

34 Exemple program sort(input, output) ;
var a : array[0..10] of integer ; x : integer ; procedure readarray ; var i : integer ; begin for i := 1 to 9 do read(a[i]) end ; procedure exchange(i, j : integer) ; begin x := a[i] ; a[i] := a[j] ; a[j] := x end ; procedure quicksort(m, n : integer) ; var k, v : integer ; function partition(y, z : integer) : integer ; var i, j : integer ; begin ... a ... v ... exchange(i, j) ; ... end ; begin ... end ; begin ... end .

35 Portée statique avec fonctions emboîtées (2/6)
sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Profondeur d'une variable Profondeur d'emboîtement de la fonction où elle est définie Une variable de profondeur v ne peut être utilisée que dans une fonction de profondeur f  v Une fonction de profondeur g ne peut être appelée que par une fonction de profondeur f  g - 1 ; f = g - 1 seulement si g est locale à f

36 Portée statique avec fonctions emboîtées (3/6)
sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Si une fonction g locale à f a un enregistrement d'activation dans la pile, alors f a un enregistrement d'activation au-dessous de celui de g (c'est l'EA le plus récent qui soit de profondeur inférieure à celle de g) L'enregistrement d'activation de f n'est pas forcément juste au-dessous de celui de g Le lien de l'EA de g vers l'EA de f est le lien d'accès

37 Portée statique avec fonctions emboîtées (4/6)
sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Si une variable est utilisée dans une fonction g, - elle est déclarée dans g ou dans une fonction h qui contient g - on la lie à un enregistrement d'activation présent dans la pile : l'enregistrement d'activation de h le plus récent - on accède à cet EA en remontant les liens d'accès - le nombre de liens d'accès est la différence de profondeur entre g et h

38 Portée statique avec fonctions emboîtées (5/6)
sort quicksort(m, n) readarray exchange(i, j) partition(y, z) Si une variable a de profondeur p(a) est utilisée dans une fonction f de profondeur p(f), on trouve son adresse : - en remontant p(f) - p(a) liens d'accès - en utilisant l'adresse relative de a dans l'enregistrement d'activation obtenu Ces deux valeurs sont connues à la compilation Elles représentent la liaison de cette occurrence de a

39 Portée statique avec fonctions emboîtées (6/6)
Calcul du lien d'accès dans la séquence d'appel Une fonction f appelle une fonction g Si p(f) = p(g) - 1 g est locale à f : le lien d'accès est égal au lien de contrôle Si p(f)  p(g) on remonte p(f) - p(g) + 1 liens d'accès depuis l'enregistrement d'activation de f Ces calculs sont faits à la compilation

40 sort a, x sort a, x sort a, x sort a, x quicksort(1, 9) k, v quicksort(1, 9) k, v quicksort(1, 9) k, v quicksort(1, 9) k, v accès accès accès accès quicksort(1, 3) k, v quicksort(1, 3) k, v quicksort(1, 3) k, v accès accès accès partition(1, 3) i, j partition(1, 3) i, j accès accès exchange(1, 3) accès

41 Fonctions passées en paramètre
program param(input, output) ; procedure b(function h(n : integer) : integer ; begin writeln(h(2)) end ; procedure c ; var m : integer ; function f(n : integer) : integer ; begin f := m + n end ; begin m := 0 ; b(f) end ; begin c end .

42 Fonctions passées en paramètre
Calcul du lien d'accès à l'appel de f param c m accès b <f ; > k, v acc Pour appeler f on a besoin de l'adresse du code et du lien d'accès accès

43 Accès direct aux noms non locaux
Une méthode plus rapide pour accéder aux noms non locaux Un tableau de pointeurs vers les enregistrements d'activation Pour chaque profondeur j, display[j] pointe vers l'enregistrement d'activation où sont placés les noms non locaux de niveau j A chaque appel on met à jour display Quand on empile un enregistrement de profondeur i, 1. sauvegarder display[i] dans le nouvel enregistrement 2. faire pointer display[i] sur le nouvel enregistrement Avant de dépiler, on restaure display[i]

44 sort sort sort sort d[1] d[1] d[1] d[1] d[2] d[2] d[2] d[2] qs(1, 9) qs(1, 9) qs(1, 9) qs(1, 9) d[2] d[2] d[2] d[2] d[3] d[3] qs(1, 3) qs(1, 3) qs(1, 3) d[2] d[2] d[2] pt(1, 3) pt(1, 3) d[3] d[3] ex(1, 3) d[2]

45 Portée dynamique Les liaisons des noms non locaux ne changent pas quand on appelle une fonction Un nom non local dans la fonction appelée est lié au même emplacement que dans la fonction appelante Réalisation On recherche l'emplacement des noms non locaux en suivant les liens de contrôle On n'a pas besoin de liens d'accès

46 Portée dynamique Résultats : portée statique 0.250 0.250
program dynamic(input, output) var r : real ; procedure show begin write(r : 5:3) end ; procedure small begin r := ; show end ; begin r := ; show ; small ; writeln ; end . Résultats : portée statique portée dynamique

47 Passage des paramètres (1/5)
Passage par valeur Les valeurs des paramètres effectifs sont passés à la procédure appelée Exemple : le langage C Réalisation Les paramètres formels sont traités comme des noms locaux Les paramètres effectifs sont évalués par l'appelant Ne modifie pas les valeurs dans l'enregistrement d'activation de l'appelant, sauf à travers des noms non locaux ou des pointeurs passés par valeur

48 Passage des paramètres (2/5)
Pascal procedure echange(i, j : integer) ; var x : integer ; begin x := a[i] ; a[i] := a[j] ; a[j] := x end C swap(int * x, * y) { int temp ; temp = * x ; * x = * y ; * y = temp ; } main() int a = 1, b = 2 ; swap(& a, &b) ;

49 Passage des paramètres (3/5)
Passage par référence Les adresses des paramètres effectifs sont passés à la procédure appelée Exemple en Pascal program reference(input, output) ; var a, b : integer ; procedure swap(var x, y : integer) ; var temp : integer ; begin temp := x ; x := y ; y := temp end ; a := 1 ; b := 2 ; swap(a, b) ; end .

50 Passage des paramètres (4/5)
Passage par copie et restauration Les valeurs des paramètres effectifs sont passées à la procédure appelée Au retour, les nouvelles valeurs des paramètres sont copiées à leur adresse Exemple : Fortran

51 Passage des paramètres (5/5)
Passage par nom Le corps de la fonction est substitué à l'appel Les paramètres sont substitués littéralement Exemples Algol Macros en C #define swapint(a, b) {int x = a ; a = b ; b = x ; } swapint(i, a[i]) affecte la valeur i à a[a[i]]


Télécharger ppt "Environnements d'exécution"

Présentations similaires


Annonces Google