1 סביבת זמן הריצה aho, sethi, and ullman – chapter 7 cooper and torczon – chapter 6
Post on 21-Dec-2015
222 views
TRANSCRIPT
1
סביבת זמן הריצה
Aho, Sethi, and Ullman – Chapter 7
Cooper and Torczon – Chapter 6
2
גישור בין זמן הידור לזמן ריצה
של המהדר בקוד הקלטהסמנטימרכיב חשוב במסגרת הטיפול
רוב הסוגיות קשורות לטיפול בקריאות לפונקציות/פרוצדורותהקריאות – דינאמיות, בזמן ריצההטיפול – סטאטי, בזמן הידור
הקצאת כתובות זכרון לכלל המשתניםכתובות שערכן נקבע ומשתנה בזמן ריצה
linkage, ABIגישור בין המהדר למערכת הפעלה, מוסכמות
3
למה פונקציה?
separation of concernsמרכיב מאד חשוב בהנדסת תוכנה, 1.בלעדיו לא היינו מצליחים לכתוב תוכניות גדולות
מרכיב מאד משמעותי לקומפיילר2.
אבסטרקציה של בקרה – קריאה וחזרה מפונקציה1. הקומפיילר מפרש לאן צריך לקפוץ בפקודתreturn
הגדרת משתנים מקומיים2. הקומפיילר מזהה את התחום של כל משתנה
ממשק בין פונקציות3.הקומפיילר דואג לקישור פרמטרים ושמירה על מוסכמות
4
, למה את/ה מתכוון/נת?xכשאת/ה אומר/ת
מה תדפיס התוכנית הבאה?
var x: int;
function foo(): int is return x;
function bar(): int is var x: int;
x = 1;
return foo();
procedure main() is x = 0;
print bar();
5
תוצאות אפשריות
0התוכנית תדפיס C ,פסקל ,C++, Java ורוב השפות
ה"מודרניות"
1התוכנית תדפיס LISP, APL, Perl... ,(לפעמים)
התוכנית תדפיס הודעת שגיאהPHP
6
מה ההבדל?
Scoping איך מחליטים – לאיזו כתובת בזכרון
מתייחס כל שם
dynamic scopingחריג –
static scoping ההכרזה – המקיפה הקרובה ביותר
main ( )
{
int a = 0 ;
int b = 0 ;
{
int b = 1 ;
{
int a = 2 ;
printf (“%d %d\n”, a, b)
}
{
int b = 3 ;
printf (“%d %d\n”, a, b) ;
}
printf (“%d %d\n”, a, b) ;
}
printf (“%d %d\n”, a, b) ;
}
B0
B1
B3B3
B2
7
dynamic scopingמימוש
לכל שם יש מחסנית (יתכן ריקה). אפשר לנהלhash table.של שמות
שבו מוגדר משתנה: דחיפה של ההגדרה scopeכניסה ל-למחסנית.
מהמחסנית.pop שבו מוגדר משתנה: scopeיציאה מ-
גישה למשתנה: לפי ראש המחסנית.
האם אפשר לגלות גישות לא חוקיות (למשתנים לא קיימים) בזמן קומפילציה?
מה לגבי בדיקות טיפוסים?
8
static scopingמימוש
המשתנה אליו מתייחס הקוד ידוע בזמן קומפילציה.
לכן, ידועה גם הכתובת שבה שוכן המשתנה. הקצאת כתובות למשתנים היא חלק מתהליך
הקומפילציה.
אין שגיאות זמן-ריצה של "גישה למשתנה לא קיים".
9
static scopingמימוש
למשל:
var x: int;
function foo(): int is return x;
function bar(): int is var x: int;
x = 1;
return foo();
procedure main() is x = 0;
print bar();
כתובת שהוקצתה עבורו
שם
432234x(גלובלי)
432238x בתוך) bar(
10
static scopingמימוש
בדוגמה הבאה?bרק רגע: מה הכתובת של המשתנה
procedure fib(n: int) is var a: int;
var b: int;
if (n ≤ 1) return 0;
a = fib(n – 1);
b = fib(n – 2);
return a + b;
procedure main() is print fib(5);
.dynamic scopingשימו לב לכך שהבעיה לא קיימת במקרה של
11
גורמים המשפיעים על ארגון הזיכרון ע"י המהדר
האם פרוצדורות יכולות להיות רקורסיביות?
מה קורה לערכים של משתנים מקומיים עם סגירת ההפעלה הנוכחית של הפרוצדורה?
האם פרוצדורות יכולות להתייחס למשתנים לא מקומיים?
איך מועברים פרמטרים?
האם אפשר להעביר פרוצדורות כפרמטרים?
האם אפשר להקצות זיכרון באופן דינאמי? האם יש צורך לשחררו באופן דינאמי?
12
ארגון הזיכרון (הוירטואלי)
code
static data
stack
heap
גודל זה ידוע בזמן קומפילציה
המחסנית גדלה וקטנה בזמן ריצה. היא activation(מכילה רשומות הפעלה
records(
הקצאת זיכרון בשליטת התוכנית
top of stack →
משתניםגלובליים
13
הכתובות של משתנים מקומיים
בכל כניסה לפרוצדורה, מוסיפים רשומת הפעלה למחסנית
בכל יציאה, מסירים רשומת הפעלה
משתנים מקומיים הם חלק מרשומת ההפעלה של כל פרוצדורה
S-aכתובת של משתנה מקומי: Sהיא כתובת ראש המחסנית; משתנה בזמן ריצה a של המשתנה המקומיהיחסית היא הכתובת
!הכתובות היחסיות נקבעות בזמן קומפילציה
14
fibדוגמה: הפעלה של
… other parts of activation record …
n (addr: S-20)a (addr: S-16)b (addr: S-12)
… other parts of activation record …
… other parts of activation record …
n (addr: S-20)a (addr: S-16)b (addr: S-12)
… other parts of activation record …
… other parts of activation record …
n (addr: S-20)a (addr: S-16)b (addr: S-12)
… other parts of activation record …
פרמטרים הםמשתנים מקומיים.
15
מה עוד יש ברשומת הפעלה?
returned valueערך מוחזר; לעיתים -- רגיסטר
actual parametersפרמטרים אקטואליים; לעיתים רגיסטרים
optional control linkמצביע לרשומת ההפעלה של הפרוצדורה הקוראת
optional access linkדרוש לפעמים על מנת להתייחס למשתנים לא מקומיים
)display(
saved machine statusמצב המכונה לפני התחלת עבודתה של הפרוצדורה הנוכחית
local dataמשתנים מקומיים
temporariesערכי ביניים
16
מה עוד יש ברשומת הפעלה?
ערך החזרה מהפונקציה – במקרים רבים נשמר ברגיסטר ולא על המחסנית
בשפות תכנות מסוימות, כתלות בסוג ערך לא)struct ישמר ברגיסטר, intהחזרה (
הפרמטרים האקטואליים (ערכי הפרמטרים) מוכנסים למחסנית על-ידי הפונקציה הקוראת
כתובת החזרהמצב המכונה – מכיל בעיקר את
ערכי ביניים – למעשה, משתנים מקומיים שהקומפיילר יצר
17
תכנון המבנה של רשומות הפעלה
בתחילת הרשומה מקצים מקום
לגדלים הידועים בזמן קומפילציה
יש לתאם בין רשומות ההפעלה
של הפרוצדורה הקוראת לפרוצדורה
הנקראת
כמות / גודל ה- temporaries נקבעת
לעתים רק אחרי תהליך
האופטימיזציה
. . .
parameters and returned value
control link
links and saved status
temporaries and local data
parameters and returned value
control link
links and saved status
temporaries and local data
top_sp
caller’sresponsibility
callee’sresponsibility
caller’sactivation
record
callee’sactivation
record
18
תהליך הקריאה
הקורא מחשב את 1.הפרמטרים האקטואליים
הקורא שומר את כתובת 2.החזרה ואת ערכו הנוכחי
top_spשל
הקורא מקדם את3.top_sp
הפרוצדורה הנקראת 4.שומרת את הרגיסטרים
statusואת שאר ה- information
הפרוצדורה הנקראת 5.מאתחלת את המשתנים
ומתחילה לפעול
. . .
parameters and returned value
control link
links and saved status
temporaries and local data
parameters and returned value
control link
links and saved status
temporaries and local data
caller’sresponsibility
callee’sresponsibility
1
top_sp3
2
4
5
19
תהליך החזרה
הפרוצדורה הנקראת 1.מאכסנת את הערך
המוחזר במקום המתאים
הפרוצדורה הנקראת 2., top_spמשחזרת את
את ערכי הרגיסטרים, statusואת ה-
information
top_sp למרות ש-3.עודכן, ניתן לגשת לערך
המוחזר
. . .
parameters and returned value
control link
links and saved status
temporaries and local data
parameters and returned value
control link
links and saved status
temporaries and local data
caller’sresponsibility
callee’sresponsibility
1
2
2
top_sp
,3
20
פרוצדורות בתוך פרוצדורות: פסקל
) מוגדרת כאוסף של שגרות programבפסקל, תוכנית ()procedure ו/או function(
לכל שגרה יכולות להיות תת-שגרות
scopesכל תת-שגרה יכולה לגשת לכל מה שהוגדר ב-המכילים אותה
21
פרוצדורות בתוך פרוצדורות: פסקל
program p;
var x: Integer;
procedure a
var y: Integer;procedure b begin…b… end;
function c
var z: Integer;procedure d begin…d… end;
begin…c…end;
begin…a… end;
begin…p… end.
מה הכתובת של משתנהy מתוך הפרוצדורה d?
סדרת קריאות אפשרית:p→a→a→c→b→c→d
22
פרוצדורות בתוך פרוצדורות: פסקל
ברשומת ההפעלהaccess linksהפתרון:
מכיל מחוון לרשומת ההפעלה access linkכל של רמת הקינון שמעליו
-למשל, הaccess link של d מכיל מחוונים .cלרשומת ההפעלה של
נבנים בזמן ריצהaccess linksה-
שצריך "לטייל" ידוע בזמן linksמספר ה-קומפילציה
23
פרוצדורות בתוך פרוצדורות: פסקל
a
a
c
b
c
d
y
y
z
z
24
display
accessהבעיה: ניהול יעיל של ה-links
השיטה: ניהול מערך בעומק הקינון הסטטי ובו מצביע לכל סביבה סטטית
כשמופעלת פרוצדורה ברמת קינוןi:מבצעים את השינוי הבא
שומרים את הערך שלd [ i ] ברשומת ההפעלה החדשה
מעדכנים אתd [ i ] להצביע על רשומת ההפעלה החדשה
ביציאה מהפרוצדורה – מבצעיםאת התהליך ההפוך
saved d [ 2 ]
q(1, 9)
sd [ 1 ]
d [ 2 ]
25
display
accessהבעיה: ניהול יעיל של ה-links
השיטה: ניהול מערך בעומק הקינון הסטטי ובו מצביע לכל סביבה סטטית
כשמופעלת פרוצדורה ברמת קינוןi:מבצעים את השינוי הבא
שומרים את הערך שלd [ i ] ברשומת ההפעלה החדשה
מעדכנים אתd [ i ] להצביע על רשומת ההפעלה החדשה
ביציאה מהפרוצדורה – מבצעיםאת התהליך ההפוך
saved d [ 2 ]
q(1, 3)
saved d [ 2 ]
q(1, 9)
sd [ 1 ]
d [ 2 ]
26
display
accessהבעיה: ניהול יעיל של ה-links
השיטה: ניהול מערך בעומק הקינון הסטטי ובו מצביע לכל סביבה סטטית
כשמופעלת פרוצדורה ברמת קינוןi:מבצעים את השינוי הבא
שומרים את הערך שלd [ i ] ברשומת ההפעלה החדשה
מעדכנים אתd [ i ] להצביע על רשומת ההפעלה החדשה
ביציאה מהפרוצדורה – מבצעיםאת התהליך ההפוך
saved d [ 3 ]
p(1, 3)
saved d [ 2 ]
q(1, 3)
saved d [ 2 ]
q(1, 9)
sd [ 1 ]
d [ 2 ]
d [ 3 ]
27
display
accessהבעיה: ניהול יעיל של ה-links
השיטה: ניהול מערך בעומק הקינון הסטטי ובו מצביע לכל סביבה סטטית
כשמופעלת פרוצדורה ברמת קינוןi:מבצעים את השינוי הבא
שומרים את הערך שלd [ i ] ברשומת ההפעלה החדשה
מעדכנים אתd [ i ] להצביע על רשומת ההפעלה החדשה
ביציאה מהפרוצדורה – מבצעיםsaved d [ 2 ]את התהליך ההפוך
e(1, 3)
saved d [ 3 ]
p(1, 3)
saved d [ 2 ]
q(1, 3)
saved d [ 2 ]
q(1, 9)
sd [ 1 ]
d [ 2 ]
d [ 3 ]
28
)r-value (העברת ה- call by valueהעברת פרמטרים –
הערה: הערך יכול להיות מצביע
procedure exchange ( i, j : integer ) ;
var x : integer ;
begin
x := a [ i ] ; a [ i ] := a [ j ] ; a [ j ] := x
end
29
(העברת כתובות) call by referenceהעברת פרמטרים –
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 ;
begin
a := 1 ; b := 2 ;
swap (a, b) ;
writeln ( ' a = ' , a ) ; writeln (' b = ' , b )
end .
by referenceגורם להעברה
30
copy restoreהעברת פרמטרים –
מעבירים ערכים; עם החזרה מעתיקים את הערכים החדשים לכתובות המקוריות
program copyout ( input, output ) ;
var a : integer ;
procedure unsafe (var x : integer ) ;
begin x := 2 ; a := 0 end ;
begin
a := 1 ; unsafe ( a ) ; writeln ( a )
end.