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 Notions de base Spécificités des langages sources Organisation de la mémoire Stratégies d'allocation mémoire Accès aux noms.

Présentations similaires


Présentation au sujet: "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."— 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 ; var i : integer ; begin... end ; procedure quicksort(m, n : integer) ; var i : 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] := ; 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 readarray partition(1, 9) quicksort(1, 3) quicksort(1, 9) quicksort(1, 0) quicksort(2, 1) quicksort(3, 3) partition(2, 3) quicksort(5, 9) sort quicksort(2, 3) partition(1,3) quicksort(5, 5) quicksort(7, 7) quicksort(9, 9) partition(7, 9) quicksort(7, 9) partition(5, 9)

8 Pile d'exécution readarray partition(1, 9) quicksort(1, 3) quicksort(1, 9) quicksort(1, 0) quicksort(5, 9) sort partition(1,3) quicksort(5, 5) partition(5, 9) sortquicksort(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 nom adressevaleur liaison état 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 statiquedynamique connu à la compilationdépend de chaque exécution définition d'une fonctionactivations d'une fonction déclaration d'un nomliaisons d'un nom portée d'une déclarationduré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 données statiques pile tas 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

13 Enregistrements d'activation Zone de mémoire empilée à l'appel d'une fonction et dépilée au retour 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 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 fond de pile 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 typecharshortintlongfloat taille (bits)81632 alignement (bits)81632 taille alignement64 machine 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) Exempleentré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 /' '/ 6C = 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 NEXT 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 valeur renvoyée paramètres lien d'accès sauvegarde de l'état machine données locales temporaires enregistrement d'activation de l'appelant à la charge de l'appelant lien de contrôle valeur renvoyée paramètres lien d'accès sauvegarde de l'état machine données locales temporaires lien de contrôle enregistrement d'activation de l'appelé 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 2 e pointeur de sommet de pile qui tient compte des données de taille variable (sommet)

25 lien d'accès sauvegarde de l'état machine enregistrement d'activation de p tableaux de p lien de contrôle 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 pointeur sur A pointeur sur B tableau A tableau B tableaux de q tableau A 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 main() { int a = 0 ; int b = 0 ; { int b = 1 ; { int a = 2 ; printf("%d %d", a, b) ; } { int b = 3 ; printf("%d %d", a, b) ; } printf("%d %d", a, b) ; } printf("%d %d", a, b) ; } B0B0 B1B1 B2B2 B3B3

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 B 2 et b de B 3 )

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 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 readarrayexchange(i, j)quicksort(m, n) sort 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) readarray partition(y, z) quicksort(m, n) sort 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 exchange(i, j)

36 Portée statique avec fonctions emboîtées (3/6) 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 readarray partition(y, z) quicksort(m, n) sort exchange(i, j)

37 Portée statique avec fonctions emboîtées (4/6) 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 readarray partition(y, z) quicksort(m, n) sort exchange(i, j)

38 Portée statique avec fonctions emboîtées (5/6) 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 readarray partition(y, z) quicksort(m, n) sort exchange(i, j)

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 quicksort(1, 9) k, v quicksort(1, 3) k, v partition(1, 3) i, j exchange(1, 3) accès sort a, x quicksort(1, 9) k, v quicksort(1, 3) k, v partition(1, 3) i, j accès sort a, x quicksort(1, 9) k, v quicksort(1, 3) k, v accès sort a, x quicksort(1, 9) k, v 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 b k, v accès acc Pour appeler f on a besoin de l'adresse du code et du lien d'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 qs(1, 9) qs(1, 3) pt(1, 3) ex(1, 3) d[2] d[3] d[2] d[1] d[2] d[3] sort qs(1, 9) qs(1, 3) pt(1, 3) d[2] d[3] d[1] d[2] d[3] sort qs(1, 9) qs(1, 3) d[2] d[1] d[2] sort qs(1, 9) d[2] d[1] 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 program dynamic(input, output) var r : real ; procedure show begin write(r : 5:3) end ; procedure small var r : real ; 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 Pascalprogram reference(input, output) ; var a, b : integer ; procedure swap(var x, y : integer) ; var temp : integer ; begin temp := x ; x := y ; y := temp end ; begin 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 Notions de base Spécificités des langages sources Organisation de la mémoire Stratégies d'allocation mémoire Accès aux noms."

Présentations similaires


Annonces Google