HY Γλώσσες και Μεταφραστές Φροντιστήριο Runtime Environment
2 Οργάνωση Μνήμης (1/3) Για τις μεταβλητές καθολικής εμβέλειας, αφού το πλήθος τους είναι γνωστό σε compile-time, δεσμεύεται για αυτές χώρος σε ένα συνεχόμενο τμήμα μνήμης. Ένας καταχορητής (globalmem) της εικονικής μηχανής θα υποδεικνύει την αρχική διεύθυνση αυτού του τμήματος. Μπορούμε να κάνουμε reference μια global μεταβλητή ως MEM[globalmem + offset].
3 Οργάνωση Μνήμης (2/3) Τα τυπικά ορίσματα και οι τοπικές μεταβλητές κάθε συνάρτησης έχουν νόημα μόνο μέσα στο context μιας κλήση της συνάρτησης. Επίσης, εάν υπάρχει αναδρομική κλήση κάποιας συνάρτησης θα πρέπει να παρέχεται ένα «περιβάλλον» για κάθε ενεργοποίηση της συνάρτησης.
4 Οργάνωση Μνήμης (3/3) Επομένως για κάθε καλούμενη συνάρτηση δεσμεύουμε μνήμη at run-time σε κάθε κλήση της. Ο λόγος είναι ότι στην alpha η συνάρτηση που θα κληθεί ίσως να μην είναι γνωστή σε compile- time. Το ίδιο συμβαίνει και στην C, C++ (π.χ. branches, late binding, dispatch table κτλ.).
5 Δέντρο ενεργοποίησης Παράδειγμα function fact (n) { if (n == 1) return 1; else return n * fact(n-1); } fact(5) fact(4) fact(3) fact(2) fact(1) Δέντρο ενεργοποίησης Κάθε ενεργοποίηση απαιτεί διαφορετικό περιβάλλον, το μέγεθος του οποίου ισούται με: αριθμός ορισμάτων + αριθμός τοπικών μεταβλητών
6 Activation records (1/6) Κατά την κλήση μιας συνάρτησης, παραχωρείται μνήμη δυναμικά (και γίνεται push στην στοίβα), ενώ μετά το τέλος της κλήσης αυτή η μνήμη απελευθερώνεται (και γίνεται pop από την στοίβα το αντίστοιχο active record).
7 Activation records (2/6) Παράδειγμα fract(5) fract(4) fract(3) fract(2) fract(1) Δέντρο ενεργοποίησης fract(1) fract(2) fract(3) fract(4) fract(5) ……. Στοίβα Η κλήση που έγινε τελευταία, βρίσκεται υψηλότερα στην στοίβα
8 Activation records (3/6) Παράδειγμα (code) function f (x, y) { z = x * y; if (z == 10) { z = 1; } return z; } i = f (j, k); 1:funcstart f 2:mul x y z 3:if_eq z :jump 6 5:assign 1 z 6:return z 7:funcendf 8:param k 9:param j 10:call f 11:getretval _t1 12:assign _t1 i
9 Activation records (4/6) Παράδειγμα (stack) k j actual_args ret_address stack saved_topsp saved_top z 108 top topsp function f (x, y) { z = x * y; if (z == 10) { z = 1; } return z; } i = f (j, k); old_top old_topsp
10 Activation records (5/6) Παράδειγμα 2 (stack) k j actual_args ret_address Στιγμιότυπο της στοίβας όταν το PC βρίσκεται μέσα στο body της ανώνυμης συνάρτησης που ορίζεται μέσα στην g() saved_topsp saved_top w 109 z 108 top topsp function g (a) { return function (x){ tmp = 2; return (tmp – x); } (a); } function f (x, y) { z = 2*x + y; w = z – x/y; g(w); return z; } i = f (j, k); w 110 ret_address 112 actual_args 111 saved_top 113 a 115 saved_topsp 114 f g ret_address 117 actual_args 116 saved_top 118 tmp 120 saved_topsp t1 stack
11 n actual_args ret_address saved_topsp saved_top n actual_args ret_address saved_topsp saved_top n actual_args ret_address saved_topsp saved_top Activation records (6/6) Παράδειγμα 3 (recursion) n actual_args ret_address Στιγμιότυπο της στοίβας όταν το PC βρίσκεται μέσα στο body της αναδρομικής fact() με όρισμα n=1 (αρχική κλήση n=4) saved_topsp saved_top top topsp f(4) stack function fact (n) { if (n == 1) return 1; else return n * fact(n-1); } x = fact(4); 105 f(3) f(2) f(1)