Εγγραφές Δραστηριοποίησης. Jackson Pollock, The Key, 1946 (action painting)

Σχετικά έγγραφα
Εγγραφές Δραστηριοποίησης

Εγγραφές Δραστηριοποίησης

Εγγραφές ραστηριοποίησης

Πανεπιστήμιο Θεσσαλίας Τμήμα Ηλεκτρολόγων Μηχανικών και Μηχανικών Υπολογιστών Τμήμα Πληροφορικής

Ονόματα και Εμβέλεια. Wassily Kandinsky, Black lines, 1913

Ανάπτυξη και Σχεδίαση Λογισμικού

Εισαγωγή στη Γλώσσα ML. Juan Miró

procedure P ( < pars > ) < type> f( < pars > ) begin { < local vars > < local vars > < procedure body> < procedure body> end; }

Εμβέλεια. Παραδείγματα. Παραδείγματα. Μπλοκ (blocks)

Προγραμματισμός Ι (ΗΥ120)

Σχεδίαση Γλωσσών Προγραμματισμού. Εαρινό Εξάμηνο Lec03 18/02/2019

Εισαγωγή στη Γλώσσα ML

Αναδρομή. ΗΥ 232 Οργάνωση και Σχεδίαση Υπολογιστών. Διάλεξη 6. Νίκος Μπέλλας Τμήμα Μηχανικών Η/Υ, Τηλεπικοινωνιών και Δικτύων

Εισαγωγή στους Η/Υ. Γιώργος Δημητρίου. Μάθημα 3-4: Προγραμματισμός MIPS. Πανεπιστήμιο Θεσσαλίας - Τμήμα Πληροφορικής

Ονόματα και Εμβέλεια 6

Δομημένος Προγραμματισμός

Εισαγωγή στον Προγραμματισμό

Προγραμματισμός Υπολογιστών & Υπολογιστική Φυσική

Ευφυής Προγραμματισμός

Ονόματα και Εμβέλεια 4

Αντικειμενοστρέφεια. Henri Matisse, Harmony in Red, Κωστής Σαγώνας Νίκος Παπασπύρου

Λογισµικό (Software SW) Γλώσσες

Παράμετροι 19/9/2007. Πέρασμα παραμέτρων. Περιεχόμενα. Θέσεις και ονόματα στο ταίριασμα παραμέτρων. Ταίριασμα παραμέτρων μέσω ονομάτων

{ int a = 5; { int b = 7; a = b + 3;

Κεφάλαιο 6 Υλοποίηση Γλωσσών Προγραμματισμού

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Δομημένος Προγραμματισμός (ΤΛ1006)

int plus(int a, int b) { return a+b; } int x = plus(1, 2); Πως περνιούνται οι παράμετροι; Αλλά θα δούμε επτά διαφορετικές μεταξύ τους τεχνικές

Διάλεξη 13η: Δυναμική Διαχείρηση Μνήμης, μέρος 1

Γλώσσες Προγραμματισμού Μεταγλωττιστές

Εισαγωγή στον Προγραμματισμό

Βασικά Στοιχεία της Java

Ανάπτυξη και Σχεδίαση Λογισμικού

ΥΠΟΠΡΟΓΡΑΜΜΑΤΑ. Κάθε υποπρόγραμμα έχει μόνο μία είσοδο και μία έξοδο. Κάθε υποπρόγραμμα πρέπει να είναι ανεξάρτητο από τα άλλα.

Κεφάλαιο 7: Υπορουτίνες

Προηγμένοι Μικροεπεξεργαστές. Έλεγχος Ροής Προγράμματος

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Προγραμματισμός Η/Υ (ΤΛ2007 )

Κεφάλαιο 7: Υποπρογράμματα. Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Συναρτήσεις-Διαδικασίες

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Κλάσεις και Αντικείμενα Αναφορές

Ονόµατα και Εµβέλεια 4

Pascal. 15 Νοεμβρίου 2011

Προγραμματισμός Η/Υ. Ενότητα 7: Συναρτήσεις

ΚΥΡΙΑ ΜΟΝΤΕΛΑ ΓΛΩΣΣΩΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ

Παράμετροι. Νίκος Παπασπύρου. Claude Monet, Poppies, 1873

Εισαγωγή στη Γλώσσα ML

2 Ορισμός Κλάσεων. Παράδειγμα: Μηχανή για Εισιτήρια. Δομή μιας Κλάσης. Ο Σκελετός της Κλάσης για τη Μηχανή. Ορισμός Πεδίων 4/3/2008

Η γλώσσα προγραμματισμού C

Βασικά Στοιχεία της Java

Σε γενικές γραμμές, είναι καλή πρακτική να γράϕουμε προγράμματα C που αποτελούνται από πολλές και μικρές συναρτήσεις, παρά από λίγες και μεγάλες.

Διδάσκων: Παναγιώτης Ανδρέου

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Chapter 2. Εντολές : Η γλώσσα του υπολογιστή. (συνέχεια) Η διασύνδεση Υλικού και λογισμικού David A. Patterson και John L.

Εισαγωγή στον Προγραμματισμό (με. τη C)

Εισαγωγή στην Επιστήμη Υπολογιστών. Εισαγωγή στην Python

Δυναμική δέσμευση και αποδέσμευση μνήμης. Προγραμματισμός II 1

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Αναφορές-Παράμετροι

ΕΙΣΑΓΩΓΗ ΣΤΟN ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΠΑΤΡΩΝ ΠΟΛΥΤΕΧΝΙΚΗ ΣΧΟΛΗ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ

Διαδικασιακός Προγραμματισμός

Προγραμματισμός Ι. Συναρτήσεις. Πανεπιστήμιο Πελοποννήσου Τμήμα Πληροφορικής & Τηλεπικοινωνιών

Μεταγλωττιστές. Γιώργος Δημητρίου. Μάθημα 8 ο. Πανεπιστήμιο Θεσσαλίας - Τμήμα Ηλεκτρολόγων Μηχανικών & Μηχανικών Υπολογιστών

Διαδικαστικός Προγραμματισμός

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

ΑΣΚΗΣΗ 6: ΔΕΙΚΤΕΣ. Σκοπός της Άσκησης. 1. Εισαγωγικά στοιχεία για τους Δείκτες

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αναφορές Στοίβα και Σωρός Μνήμης Αντικείμενα ως ορίσματα

Δομές Δεδομένων (Εργ.) Ακ. Έτος Διδάσκων: Ευάγγελος Σπύρου. Εργαστήριο 3 Επανάληψη Γ μέρος

Εργαστήριο 1: Επανάληψη Βασικών Εννοιών στη Γλώσσα C

Διαδικασιακός Προγραμματισμός

Διάλεξη 13: Δομές Δεδομένων ΙΙ (Ταξινομημένες Λίστες)

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Εισαγωγή στον δομημένο προγραμματισμό

Η Γλώσσα Προγραµµατισµού C++ (The C++ Programming Language)

Δείκτες (Pointers) Ένας δείκτης είναι μια μεταβλητή με τιμή μια διεύθυνση μνήμης. 9.8

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

ΣΧΕΔΙΑΣΗ ΚΑΙ ΥΛΟΠΟΙΗΣΗ ΛΟΓΙΣΜΙΚΟΥ

- Το πρόγραµµα σας δίνει τα αναµενόµενα αποτελέσµατα.

Εισαγωγή στον δομημένο προγραμματισμό

Δομές Δεδομένων (Data Structures)

Διδάσκων: Κωνσταντίνος Κώστα Διαφάνειες: Δημήτρης Ζεϊναλιπούρ

ΣΥΝΑΡΤΗΣΕΙΣ Εισαγωγή αρθρωτό ιεραρχική Προσοχή!

3ο σετ σημειώσεων - Πίνακες, συμβολοσειρές, συναρτήσεις

Προγραμματισμός Ι. Δείκτες. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Αρχές Γλωσσών Προγραμματισμου Χρήστος Νομικός Τμήμα Μηχανικών Η/Υ και Πληροφορικής Πανεπιστήμιο Ιωαννίνων 2015 Χρήστος Νομικός ( Τμήμα Μηχανικών Αρχές

Κεφάλαιο 4: Μεταβλητές, Εκφράσεις, Εντολές. Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Προγραμματισμός Η/Υ (ΤΛ2007 )

Κεφάλαιο 10 ο Υποπρογράµµατα

Η βασική συνάρτηση προγράμματος main()

Αρχές Γλωσσών Προγραμματισμού και Μεταφραστών

Στοίβες με Δυναμική Δέσμευση Μνήμης

Διαδικασίες Ι. ΗΥ 134 Εισαγωγή στην Οργάνωση και στον Σχεδιασμό Υπολογιστών Ι. Διάλεξη 4

Κλήση Συναρτήσεων ΚΛΗΣΗ ΣΥΝΑΡΤΗΣΕΩΝ. Γεώργιος Παπαϊωάννου ( )

Ορισμός μεταβλητών δεικτών και αρχικοποίηση

ΤΕΧΝΙΚΕΣ ΑΝΤΙΚΕΙΜΕΝΟΣΤΡΑΦΟΥΣ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ. Αντικείμενα ως ορίσματα Εισαγωγή στις αναφορές

ΥΠΟΠΡΟΓΡΑΜΜΑΤΑ. Διαδικασίες και συναρτήσεις. 22 Νοε 2008 Ανάπτυξη εφαρμογών/ Υποπρογράμματα 1

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΕΡΓΑΣΤΗΡΙΟ 8: Πολυδιάστατοι Πίνακες και Δυναμική Δέσμευση Μνήμης

Προγραμματισμός ΙI (Θ)

Ορισμός Συναρτήσεων στην ΜL

ΕΡΓΑΣΤΗΡΙΟ 1 - ΣΗΜΕΙΩΣΕΙΣ

Transcript:

Εγγραφές Δραστηριοποίησης Jackson Pollock, The Key, 1946 (action painting) Κωστής Σαγώνας <kostis@cs.ntua.gr>

Ερώτηση για δέσιμο Κατά την εκτέλεση του προγράμματος, οι μεταβλητές δένονται (δυναμικά) με τιμές Οι τιμές αυτές πρέπει να αποθηκευτούν κάπου Κατά συνέπεια, οι μεταβλητές πρέπει κάπως να δεθούν με θέσεις μνήμης Πώς γίνεται αυτό; Εγγραφές δραστηριοποίησης 2

Συναρτησιακές γλώσσες συναντούν προστακτικές Οι προστακτικές γλώσσες κάνουν εμφανή την έννοια των θέσεων μνήμης: a := 42 Αποθήκευσε τον αριθμό 42 στη θέση μνήμης της μεταβλητής a Οι συναρτησιακές γλώσσες τις κρύβουν: val a = 42 Δέσε το όνομα a με την τιμή 42 Και τα δύο είδη γλωσσών πρέπει να ενώσουν μεταβλητές με τιμές που αναπαρίστανται στη μνήμη Άρα και οι δύο πρέπει να αντιμετωπίσουν την ίδια ερώτηση δεσίματος Εγγραφές δραστηριοποίησης 3

Περιεχόμενα Εγγραφές δραστηριοποίησης (s) Στατική δέσμευση εγγραφών δραστηριοποίησης Στοίβες από εγγραφές δραστηριοποίησης Χειρισμός φωλιασμένων ορισμών συναρτήσεων Συναρτήσεις ως παράμετροι Μακρόβιες εγγραφές δραστηριοποίησης Εγγραφές δραστηριοποίησης 4

Δραστηριοποιήσεις συναρτήσεων Ο χρόνος ζωής της εκτέλεσης μιας συνάρτησης, από τη στιγμή της κλήσης μέχρι την αντίστοιχη επιστροφή, ονομάζεται δραστηριοποίηση (activation) της συνάρτησης Όταν κάθε δραστηριοποίηση έχει το δικό της δέσιμο μεταβλητών σε θέσεις μνήμης, λέμε ότι έχουμε μεταβλητές ειδικές για κάθε δραστηριοποίηση Οι μεταβλητές αυτές ονομάζονται επίσης δυναμικές (dynamic) ή αυτόματες (automatic) μεταβλητές Εγγραφές δραστηριοποίησης 5

Μεταβλητές ειδικές για κάθε δραστηριοποίηση Στις περισσότερες μοντέρνες γλώσσες προγραμματισμού, οι πιο συνήθεις αυτόματες μεταβλητές είναι αυτές που είναι βοηθητικές για κάθε δραστηριοποίηση συνάρτησης: fun days2ms days = let val hours = days * 24.0 val minutes = hours * 60.0 val seconds = minutes * 60.0 in seconds * 1000.0 end; Εγγραφές δραστηριοποίησης 6

Δραστηριοποίηση των μπλοκ Για μπλοκ που περιέχουν κώδικα, μιλάμε για Τη δραστηριοποίηση του μπλοκ Το χρόνο ζωής μιας εκτέλεσης του μπλοκ Μια μεταβλητή μπορεί να είναι ειδική για κάποια μόνο δραστηριοποίηση ενός συγκεκριμένου μπλοκ μιας συνάρτησης: fun fact n = if n = 0 then 1 else let val fac = fact (n-1) in n*fac end; Εγγραφές δραστηριοποίησης 7

Χρόνοι ζωής για τις μεταβλητές Οι περισσότερες προστακτικές γλώσσες έχουν κάποιο τρόπο να δηλώσουν ότι κάποιες μεταβλητές δένονται με μια συγκεκριμένη θέση μνήμης για όλη τη διάρκεια της εκτέλεσης του προγράμματος Προφανής λύση δέσμευσης: στατική δέσμευση (ο φορτωτής δεσμεύει χώρο για αυτές τις μεταβλητές) int count = 0; int nextcount() { count = count + 1; return count; } Εγγραφές δραστηριοποίησης 8

Η εμβέλεια και ο χρόνος ζωής διαφέρουν Στις περισσότερες μοντέρνες γλώσσες, οι μεταβλητές με τοπική εμβέλεια έχουν χρόνο ζωής που συνήθως ταυτίζεται με τη δραστηριοποίηση του μπλοκ Όμως, οι δύο έννοιες είναι διαφορετικές μεταξύ τους, όπως π.χ. μπορεί να γίνει στη C μέσω του προσδιοριστή static: int nextcount() { static int count = 0; count = count + 1; return count; } Εγγραφές δραστηριοποίησης 9

Άλλοι χρόνοι ζωής για τις μεταβλητές Οι γλώσσες αντικειμενοστρεφούς προγραμματισμού χρησιμοποιούν μεταβλητές των οποίων ο χρόνος ζωής είναι συσχετισμένος με το χρόνο ζωής των αντίστοιχων αντικειμένων Κάποιες γλώσσες έχουν μεταβλητές των οποίων οι τιμές είναι επίμονες (persistent): με άλλα λόγια οι μεταβλητές διατηρούν τις τιμές τους για πολλαπλές εκτελέσεις του ίδιου προγράμματος Εγγραφές δραστηριοποίησης 10

Εγγραφές δραστηριοποίησης Οι υλοποιήσεις των γλωσσών συνήθως συσκευάζουν όλες τις μεταβλητές που αναφέρονται σε μια συγκεκριμένη δραστηριοποίηση της συνάρτησης σε μια εγγραφή δραστηριοποίησης () Οι εγγραφές δραστηριοποίησης περιέχουν επίσης και όλα τα άλλα δεδομένα που σχετίζονται με δραστηριοποιήσεις, όπως: Τη διεύθυνση επιστροφής () της δραστηριοποίησης: δείχνει σε ποιο σημείο του προγράμματος πρέπει να πάει ο έλεγχος όταν επιστρέψει η συγκεκριμένη δραστηριοποίηση Ένα σύνδεσμο πρόσβασης (access link) που δείχνει την εγγραφή δραστηριοποίησης της καλούσας συνάρτησης (calling function) Εγγραφές δραστηριοποίησης 11

Εγγραφές δραστηριοποίησης για μπλοκ Όταν εκτελείται ένα μπλοκ κώδικα, χρειαζόμαστε χώρο για τις τοπικές μεταβλητές του συγκεκριμένου μπλοκ Υπάρχουν διάφοροι τρόποι δέσμευσης αυτού του χώρου: Δεσμεύουμε από πριν χώρο στην εγγραφή δραστηριοποίησης της περικλείουσας συνάρτησης Επεκτείνουμε την εγγραφή δραστηριοποίησης της συνάρτησης όταν η εκτέλεση εισέλθει στο μπλοκ (και τη μειώνουμε ξανά όταν εξέλθουμε του μπλοκ) Δεσμεύουμε κάποια ξεχωριστή εγγραφή δραστηριοποίησης για το μπλοκ Θα δούμε τον πρώτο από αυτούς τους τρόπους Εγγραφές δραστηριοποίησης 12

Στατική δέσμευση (static allocation) Η απλούστερη προσέγγιση: δέσμευση μίας εγγραφής δραστηριοποίησης για κάθε μια συνάρτηση, στατικά Οι παλιές διάλεκτοι της Fortran και της Cobol χρησιμοποιούσαν (μόνο) αυτό το σύστημα δέσμευσης Αποτελεί απλό και πολύ γρήγορο τρόπο υλοποίησης Εγγραφές δραστηριοποίησης 13

Παράδειγμα FUNCTION AVG (ARR, N) DIMENSION ARR(N) SUM = 0.0 DO 100 I = 1, N SUM = SUM + ARR(I) 100 CONTINUE AVG = SUM / FLOAT(N) RETURN END N address ARR address I SUM AVG Εγγραφές δραστηριοποίησης 14

Μειονέκτημα στατικής δέσμευσης Κάθε συνάρτηση έχει μία εγγραφή δραστηριοποίησης Μπορεί να υπάρξει μία μόνο δραστηριοποίηση συνάρτησης ζωντανή κάθε χρονική στιγμή! Οι μοντέρνες γλώσσες (συμπεριλαμβανομένων των μοντέρνων διαλέκτων της Cobol και της Fortran) δεν υπακούν σε αυτόν τον περιορισμό λόγω: Αναδρομής Πολυνηματικότητας (multithreading) Εγγραφές δραστηριοποίησης 15

Στοίβες από εγγραφές δραστηριοποίησης (1) Για την υποστήριξη αναδρομής, πρέπει να δεσμεύσουμε μια νέα εγγραφή δραστηριοποίησης για κάθε δραστηριοποίηση της συνάρτησης Δυναμική δέσμευση: η εγγραφή δραστηριοποίησης δεσμεύεται όταν η συνάρτηση καλείται Σε πολλές γλώσσες, όπως η C, η εγγραφή αυτή αποδεσμεύεται όταν η συνάρτηση επιστρέψει Εγγραφές δραστηριοποίησης 16

Στοίβες από εγγραφές δραστηριοποίησης (2) Με άλλα λόγια, η εκτέλεση δημιουργεί μια στοίβα από εγγραφές δραστηριοποίησης, όπου πλαίσια (frames) σπρώχνονται στη στοίβα κατά την κλήση των συναρτήσεων, και απομακρύνονται από τη στοίβα κατά την επιστροφή των συναρτήσεων Εγγραφές δραστηριοποίησης 17

Τρέχουσα εγγραφή δραστηριοποίησης Στη στατική δέσμευση η θέση κάθε εγγραφής δραστηριοποίησης καθορίζεται πριν την έναρξη εκτέλεσης του προγράμματος Στη δυναμική δέσμευση η θέση της τρέχουσας εγγραφής δραστηριοποίησης (current ) δεν είναι γνωστή παρά μόνο κατά το χρόνο εκτέλεσης Κάθε συνάρτηση πρέπει να ξέρει πως θα βρει τη διεύθυνση της τρέχουσας εγγραφής δραστηριοποίησης Συχνά, ένας καταχωρητής της μηχανής δεσμεύεται για να περιέχει/κρατάει τη συγκεκριμένη τιμή Εγγραφές δραστηριοποίησης 18

Παράδειγμα σε C Αποτιμούμε την κλήση fact(3). Η εικόνα δείχνει τα περιεχόμενα της στοίβας ακριβώς πριν την αναδρομική κλήση της fact(2) που θα δημιουργήσει τη δεύτερη εγγραφή δραστηριοποίησης. int fact(int n) { int result; if (n < 2) result = 1; else result = n * fact(n-1); return result; } current activation record n: 3 result:? Εγγραφές δραστηριοποίησης 19

Τα περιεχόμενα της μνήμης ακριβώς πριν την τρίτη δραστηριοποίηση. int fact(int n) { int result; if (n < 2) result = 1; else result = n * fact(n-1); return result; } current n: 2 result:? n: 3 result:? Εγγραφές δραστηριοποίησης 20

Τα περιεχόμενα της μνήμης ακριβώς πριν επιστρέψει η τρίτη δραστηριοποίηση. int fact(int n) { int result; if (n < 2) result = 1; else result = n * fact(n-1); return result; } current n: 1 result: 1 n: 2 result:? n: 3 result:? Εγγραφές δραστηριοποίησης 21

Η δεύτερη δραστηριοποίηση ακριβώς πριν επιστρέψει. int fact(int n) { int result; if (n < 2) result = 1; else result = n * fact(n-1); return result; } current n: 1 result: 1 n: 2 result: 2 n: 3 result:? Εγγραφές δραστηριοποίησης 22

Ηπρώτη δραστηριοποίηση ακριβώς πριν επιστρέψει με το αποτέλεσμα fact(3) = 6. int fact(int n) { int result; if (n < 2) result = 1; else result = n * fact(n-1); return result; } current n: 1 result: 1 n: 2 result: 2 n: 3 result: 6 Εγγραφές δραστηριοποίησης 23

Παράδειγμα σε ML Αποτιμούμε την κλήση halve [1,2,3,4] Η εικόνα δείχνει τα περιεχόμενα της μνήμης ακριβώς πριν την αναδρομική κλήση που δημιουργεί τη δεύτερη δραστηριοποίηση. fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; Οι εικόνες περιλαμβάνουν μια μικρή απλοποίηση όσον αφορά στο τι πράγματι αποθηκεύεται στη στοίβα current activation record parameter: [1,2,3,4] a: 1 b: 2 cs: [3,4] x:? y:? value to return:? Εγγραφές δραστηριοποίησης 24

Τα περιεχόμενα της μνήμης ακριβώς πριν την τρίτη δραστηριοποίηση. current parameter: [3,4] a: 3 parameter: [1,2,3,4] a: 1 fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; b: 4 b: 2 cs: [] cs: [3,4] x:? x:? y:? y:? value to return:? value to return:? Εγγραφές δραστηριοποίησης 25

current Τα περιεχόμενα της μνήμης ακριβώς πριν επιστρέψει η τρίτη δραστηριοποίηση. parameter: [] value to return: ([], []) parameter: [3,4] a: 3 parameter: [1,2,3,4] a: 1 fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; b: 4 b: 2 cs: [] cs: [3,4] x:? x:? y:? y:? value to return:? value to return:? Εγγραφές δραστηριοποίησης 26

Η δεύτερη δραστηριοποίηση ακριβώς πριν επιστρέψει. current parameter: [] value to return: ([], []) fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; parameter: [3,4] a: 3 b: 4 cs: [] x: [] y: [] value to return: ([3], [4]) parameter: [1,2,3,4] a: 1 b: 2 cs: [3,4] x:? y:? value to return:? Εγγραφές δραστηριοποίησης 27

Η πρώτη δραστηριοποίηση ακριβώς πριν επιστρέψει με το αποτέλεσμα halve [1,2,3,4] = ([1,3],[2,4]) current parameter: [] value to return: ([], []) fun halve nil = (nil, nil) halve [a] = ([a], nil) halve (a::b::cs) = let val (x, y) = halve cs in (a::x, b::y) end; parameter: [3,4] a: 3 b: 4 cs: [] x: [] y: [] value to return: ([3], [4]) parameter: [1,2,3,4] a: 1 b: 2 cs: [3,4] x: [3] y: [4] value to return: ([1,3],[2,4]) Εγγραφές δραστηριοποίησης 28

Χειρισμός φωλιασμένων συναρτήσεων Εγγραφές δραστηριοποίησης 29

Φωλιασμένες συναρτήσεις Ό,τι είδαμε μέχρι στιγμής επαρκεί για πολλές γλώσσες, συμπεριλαμβανομένης της C Αλλά όχι για γλώσσες που επιτρέπουν το ακόλουθο τρικ: Οι ορισμοί των συναρτήσεων μπορεί να είναι φωλιασμένες μέσα σε άλλους ορισμούς συναρτήσεων Οι εσωτερικές συναρτήσεις μπορεί να αναφέρονται σε τοπικές μεταβλητές των εξωτερικών συναρτήσεων (ακολουθώντας τους συνήθεις κανόνες εμβέλειας όταν υπάρχουν μπλοκ) Δηλαδή δεν επαρκεί για γλώσσες όπως η ML, η Ada, η Pascal, κ.α. Εγγραφές δραστηριοποίησης 30

Παράδειγμα fun quicksort nil = nil quicksort (pivot::rest) = let fun split nil = (nil, nil) split (x::xs) = let val (below, above) = split xs in if x < pivot then (x::below, above) else (below, x::above) end; val (below, above) = split rest in quicksort below @ [pivot] @ quicksort above end; Εγγραφές δραστηριοποίησης 31

Το πρόβλημα Πώς μπορεί η δραστηριοποίηση της εσωτερικής συνάρτησης (split) να βρει την εγγραφή δραστηριοποίησης της εξωτερικής συνάρτησης (quicksort); Παρατηρήστε ότι δεν είναι απαραίτητα η προηγούμενη εγγραφή δραστηριοποίησης, επειδή η συνάρτηση που κάλεσε την εσωτερική συνάρτηση: μπορεί να είναι μια άλλη εσωτερική συνάρτηση, ή μπορεί να είναι μια αναδρομική κλήση συνάρτησης (όπως συμβαίνει στο παράδειγμά μας με τη split) Εγγραφές δραστηριοποίησης 32

current a split activation another split activation first caller: a quicksort activation parameter parameter... parameter split s variables: x, xs, etc. split s variables: x, xs, etc. quicksort s variables: pivot, rest, etc. Εγγραφές δραστηριοποίησης 33

Σύνδεσμος φωλιάσματος (nesting link) Μια εσωτερική συνάρτηση πρέπει να είναι σε θέση να βρει τη διεύθυνση της πιο πρόσφατης δραστηριοποίησης της αμέσως εξωτερικής της συνάρτησης Μπορούμε να κρατήσουμε αυτό το σύνδεσμο στην εγγραφή δραστηριοποίησης Εγγραφές δραστηριοποίησης 34

current a split activation another split activation first caller: a quicksort activation parameter parameter... parameter nesting link nesting link nesting link: null split s variables: x, xs, etc. split s variables: x, xs, etc. quicksort s variables: pivot, rest, etc. Εγγραφές δραστηριοποίησης 35

Πως παίρνουν τιμές οι σύνδεσμοι φωλιάσματος; Εύκολα αν υπάρχει μόνο ένα επίπεδο φωλιάσματος Όταν καλείται μια εξωτερική συνάρτηση: θέτουμε την τιμή null στο σύνδεσμο Όταν καλείται μια εσωτερική συνάρτηση από μία εξωτερική: ο σύνδεσμος φωλιάσματος παίρνει ως τιμή την εγγραφή δραστηριοποίησης της καλούσας συνάρτησης Όταν καλείται μια εσωτερική συνάρτηση από μία εσωτερική: ο σύνδεσμος φωλιάσματος παίρνει ως τιμή το σύνδεσμο φωλιάσματος της καλούσας συνάρτησης Πιο πολύπλοκα από τον παραπάνω τρόπο εάν υπάρχουν πολλαπλά επίπεδα φωλιάσματος Εγγραφές δραστηριοποίησης 36

Πολλαπλά επίπεδα φωλιάσματος function f1 variable v1 function f2 variable v2 function f3 variable v3 Οι αναφορές στο ίδιο επίπεδο (π.χ. της f1 στη v1, της f2 στη v2, ) χρησιμοποιούν την τρέχουσα εγγραφή δραστηριοποίησης Οι αναφορές σε ονόματα που βρίσκονται σε κ επίπεδα φωλιάσματος διατρέχουν κ συνδέσμους της αλυσίδας Εγγραφές δραστηριοποίησης 37

Αυτή και άλλες λύσεις Το πρόβλημα είναι οι αναφορές από εσωτερικές συναρτήσεις σε μεταβλητές κάποιας εξωτερικής Λύσεις του προβλήματος αποτελούν οι: Σύνδεσμοι φωλιάσματος των εγγραφών δραστηριοποίησης (όπως δείξαμε στις προηγούμενες διαφάνειες) Displays: οι σύνδεσμοι φωλιάσματος δε βρίσκονται στις εγγραφές δραστηριοποίησης, αλλά συλλέγονται σε ένα στατικό πίνακα Λάμβδα άρση (Lambda lifting): οι αναφορές του προγράμματος αντικαθίστανται από αναφορές σε νέες, κρυφές παραμέτρους Εγγραφές δραστηριοποίησης 38

Παράδειγμα λάμβδα άρσης fun quicksort nil = nil quicksort (pivot::rest) = let fun split (nil, _) = (nil, nil) split (x::xs, lpv) = let val (below, above) = split (xs, lpv) in if x < lpv then (x::below, above) else (below, x::above) end; val (below, above) = split (rest, pivot) in quicksort below @ [pivot] @ quicksort above end; Εγγραφές δραστηριοποίησης 39

Συναρτήσεις ως παράμετροι Εγγραφές δραστηριοποίησης 40

Συναρτήσεις ως παράμετροι Όταν περνάμε μια συνάρτηση ως παράμετρο, τι ακριβώς είναι αυτό που πρέπει να μεταβιβαστεί; Οκώδικαςτηςσυνάρτησηςπρέπειναείναιμέροςαυτού που περνιέται: είτε σε μορφή πηγαίου κώδικα, ήσε μορφή μεταγλωττισμένου κώδικα, ή ως δείκτης σε κώδικα, ή μέσω υλοποίησης κάποιας άλλης μορφής Κάποιες γλώσσες, χρειάζονται κάτι περισσότερο Εγγραφές δραστηριοποίησης 41

Παράδειγμα fun addxtoall (x,thelist) = let fun addx y = y + x in map addx thelist end; Η παραπάνω συνάρτηση προσθέτει την τιμή του x σε κάθε στοιχείο της λίστας thelist Η addxtoall καλεί τη map, η map καλεί τη addx, και η addx αναφέρεται στη μεταβλητή x στην εγγραφή δραστηριοποίησης της συνάρτησης addxtoall Εγγραφές δραστηριοποίησης 42

Σύνδεσμοι φωλιάσματος ξανά Όταν η map καλέσει την addx, τι σύνδεσμος φωλιάσματος θα δοθεί στην addx; Όχι η εγγραφή δραστηριοποίησης της map διότι η addx δεν είναι φωλιασμένη μέσα στη map Όχι ο σύνδεσμος φωλιάσματος της map διότι η map δεν είναι κάπου φωλιασμένη Για να δουλέψει η συνάρτηση addxtoall, η παράμετρος που περνά η addx στη map πρέπει να περιλαμβάνει το σύνδεσμο φωλιάσματος που θα χρησιμοποιηθεί όταν κληθεί η addx fun addxtoall (x,thelist) = let fun addx y = y + x in map addx thelist end; Εγγραφές δραστηριοποίησης 43

Όχι μόνο για τις παραμέτρους Πολλές γλώσσες επιτρέπουν σε συναρτήσεις να περαστούν ως παράμετροι Οι συναρτησιακές γλώσσες επιτρέπουν περισσότερα είδη λειτουργιών σε συναρτήσεις-τιμές: Πέρασμα συναρτήσεων ως παραμέτρους Επιστροφή συναρτήσεων από συναρτήσεις Κατασκευή συναρτήσεων από εκφράσεις Οι συναρτήσεις-τιμές περιλαμβάνουν τόσο τον κώδικα που θα εκτελεστεί όσο και το σύνδεσμο φωλιάσματος που θα χρησιμοποιηθεί όταν κληθεί η συνάρτηση Εγγραφές δραστηριοποίησης 44

Παράδειγμα current activation record parameter nesting link y => y + x fun addxtoall (x,thelist) = let fun addx y = y + x in map addx thelist end; x thelist addx Τα περιεχόμενα της μνήμης ακριβώς πριν την κλήση της map. Η μεταβλητή addx είναι δεμένη με μια συνάρτηση-τιμή η οποία περιλαμβάνει κώδικα και ένα σύνδεσμο φωλιάσματος. Εγγραφές δραστηριοποίησης 45

Μακρόβιες εγγραφές δραστηριοποίησης Εγγραφές δραστηριοποίησης 46

Μια ακόμα περιπλοκή Τι συμβαίνει εάν μια συνάρτηση-τιμή χρησιμοποιείται από τη συνάρτηση που τη δημιούργησε μετά την επιστροφή της συνάρτησης-δημιουργού; val test = let val f = funtoaddx 3 in f 5 end; fun funtoaddx x = let fun addx y = y + x in addx end; Εγγραφές δραστηριοποίησης 47

val test = let val f = funtoaddx 3 in f 5 end; fun funtoaddx x = let fun addx y = y + x in addx end; current activation record parameter x: 3 nesting link: null addx nesting link: null f:? Τα περιεχόμενα της μνήμης ακριβώς πριν η funtoaddx επιστρέψει. y => y + x Εγγραφές δραστηριοποίησης 48

val test = let val f = funtoaddx 3 in f 5 end; fun funtoaddx x = let fun addx y = y + x in addx end; parameter x: 3 nesting link: null addx current activation record nesting link: null f Μετά την επιστροφή της funtoaddx, η f δεσμεύεται με τη νέα συνάρτηση-τιμή. y => y + x Εγγραφές δραστηριοποίησης 49

Το πρόβλημα Όταν η test καλέσει την f, η συνάρτηση θα χρησιμοποιήσει το σύνδεσμο φωλιάσματος για να προσπελάσει το x Με άλλα λόγια, θα χρησιμοποιήσει ένα δείκτη σε μια εγγραφή δραστηριοποίησης για μια δραστηριοποίηση που έχει τερματίσει Αυτό θα αποτύχει εάν η υλοποίηση της γλώσσας αποδεσμεύσει την εγγραφή δραστηριοποίησης τη στιγμή επιστροφής της συνάρτησης Εγγραφές δραστηριοποίησης 50

Ηλύσητουπροβλήματος Στην ML, και σε άλλες γλώσσες όπου υπάρχει η ίδια περιπλοκή, οι εγγραφές δραστηριοποίησης δε μπορούν πάντα να δεσμευθούν και να αποδεσμευθούν ακολουθώντας δομή στοίβας Αυτό διότι ακόμα και όταν μια συνάρτηση επιστρέψει, μπορεί να υπάρχουν σύνδεσμοι στην εγγραφή δραστηριοποίησής της Οι εγγραφές δε μπορεί να αποδεσμευθούν παρά μόνο όταν καταστούν απροσπέλαστες Αυτό συνήθως συμβαίνει με αυτόματη διαχείριση μνήμης ήαλλιώς με συλλογή σκουπιδιών (garbage collection) Εγγραφές δραστηριοποίησης 51

Συμπερασματικά Όσο πιο σοφιστικέ είναι μια γλώσσα, τόσο πιο δύσκολο είναι να δεθούν οι μεταβλητές με θέσεις μνήμης Στατική δέσμευση: δουλεύει σε γλώσσες που επιτρέπουν το πολύ μια δραστηριοποίηση κάθε συνάρτησης κάθε στιγμή (όπως σε πρώιμες διαλέκτους της Fortran και της Cobol) Δυναμική δέσμευση σε στοίβα: δουλεύει σε γλώσσες που δεν επιτρέπουν φωλιασμένες συναρτήσεις (όπως η C) Σύνδεσμοι φωλιάσματος (ή κάτι αντίστοιχο): επιβάλλεται σε γλώσσες που επιτρέπουν φωλιασμένες συναρτήσεις (όπως η ML, η Ada και η Pascal). Οι συναρτήσεις τιμές πρέπει να περιλαμβάνουν τόσο κώδικα όσο και σύνδεσμο φωλιάσματος Κάποιες γλώσσες (όπως η ML) επιτρέπουν αναφορές σε εγγραφές δραστηριοποιήσεων συναρτήσεων που έχουν περατώσει την εκτέλεσή τους. Κατά συνέπεια, οι εγγραφές δραστηριοποίησης δε μπορούν να αποδεσμευθούν αμέσως μετά την επιστροφή τους και η χρήση στοίβας δεν επαρκεί. Εγγραφές δραστηριοποίησης 52