520 likes | 529 Views
Subject Name Compiler Design Subject Code: 10CS63 Prepared By: Deepa, Dharmalingham, Besty Department: CSE Date :10.05.15. RUNTIME ENVIRONMENTS. Objectives. Run Time Environments Source Language Issues Storage Organization & Allocation Strategies Access to Non-local Names
E N D
Subject Name Compiler Design Subject Code: 10CS63 Prepared By: Deepa, Dharmalingham, Besty Department: CSE Date :10.05.15
Objectives • Run Time Environments • Source Language Issues • Storage Organization & Allocation Strategies • Access to Non-local Names • Parameter Passing • Symbol Tables • Language Facilities for Dynamic Storage Allocation • Dynamic Storage Allocation Techniques
Run Time Environment • Relate the static source text of a program to the actions that must occur at RUN TIME • run-time support package • consists of routines loaded with the generated target code • Handles allocation and de-allocation of data objects • As execution proceeds, The same data name in the source text can denote different data objects in the target machine ; For example: • Local Variables and global variables with same name • Local variables in a recursive execution Here we consider relations between names & data objects
Source Language Issues • run-time support package is influenced by the semantics of the procedure call in the source language • Procedure Handling Each execution of a procedure is called an activation that may manipulate data objects allocated for use A procedure definition is a declaration that, in its simplest form, associates an identifier with a statement. • The identifier is the procedure • The statement is the body of the procedure. • A complete program is also treated as a procedure
Flow of Control in Procedures • Following assumptions are made: • Control flows sequentially • Each procedure starts at the beginning of the procedure body and returns control to the point immediately following the call. • Each execution of a procedure is called an activation and the lifetime of the activation is from the first statement to the last statement of the procedure. • If two procedure activations have common lifetime then one should be totally embedded within the other – properly nested. • Same procedure can be activated within one procedure – called recursion . It may be directly calling itself but can also indirectly thru another proc.
Control Flow Representation • Done using a tree notation called Activation Tree • In an Activation Tree • Each node represents an activation of a procedure • The root represents the activation of the main program • a is a parent of b, if control flows from a to b. • Node a is left of node b if the lifetime of a is before that of b.
program sort (input, output) • var a : array [0..10] of integer; • procedure readarray; var i :integer; begin for k:= 1 to 9 do read (a [ I ] ) end; • function partition (y, z :integer) :integer; var i, j, x, v :integer; begin …. end; • procedure quicksort ( m, n: integer ); var i :integer; begin • if ( m > n ) then • begin i:= partition (m,n); quicksort(m, i- 1); quicksort(i+1, n); end; end; • begin a[0] := -9999; a[10] := 9999; • readarray; quicksort; end; QUICKSORTProgram
program sort (input, output) • var a : array [0..10] of integer; • procedure readarray; var i :integer; begin for k:= 1 to 9 do read (a [ I ] ) end; • function partition (y,z:integer):integer; var i, j, x, v :integer; begin …. end; • procedure quicksort ( m, n: integer ); var i :integer; begin • if ( m > n ) then • begin i:= partition(m,n); quicksort(m,i-1 ); quicksort(i+1, n); end; end; • begin a[0] := -9999; a[10] := 9999; • readarray; quicksort; end; QUICKSORTProgram • execution begins • enter readarray • leave readarray • enter quicksort (1 ,9 ) • enter partition ( 1 , 9) • leave partition ( 1 , 9 ) • enter quicksort ( 1 , 3 ) • … • leave quicksort ( 1 , 3 ) • enter quicksort ( 5 , 9 ) • … • leave quicksort ( 5 , 9 ) • leave quicksort ( 1 , 9 ) • execution terminated
Activation Tree for QUICKSORT • execution begins • enter readarray • leave readarray • enter quicksort (1 ,9 ) • enter partition ( 1 , 9) • leave partition ( 1 , 9 ) • enter quicksort ( 1 , 3 ) • … • leave quicksort ( 1 , 3 ) • enter quicksort ( 5 , 9 ) • … • leave quicksort ( 5 , 9 ) • leave quicksort ( 1 , 9 ) • execution terminated s r q ( 1,9) q (1,3) q (5,9) p (1,9) p(5,9) q (5,5) q (7,9) p(1,3) q (1,0) q (2,3) p(7,9) q(7,7) q (9, 9) p(2,3) q(2,1) q (3,3)
The Control Flow Observation • The flow of control in a program corresponds to a depth-first traversal ( pre-order) of the activation tree. • Starts at the root • Visit a node before the children • Recursively visit children in left right order. • A stack called Control Stack can be used keep track of live procedure • Push the node onto control stack when activation begins & • Pop it when completed • When node is at the top of the stack, the stack contains the nodes along the path from n to the root
s s r q ( 1,9) r q ( 1,9) p (1,9) q (1,3) q (5,9) q (1,3) q (5,9) p (1,9) p(1,3) q (1,0) q (2,3) p(5,9) q (5,5) q (7,9) p(1,3) q (1,0) q (2,3) p(7,9) q(7,7) q (9,9) p(2,3) q(2,1) q (3,3) Control Stack Example • The stack would contain → • Control Stacks are used in storage allocation for data objects
Declaration & its Scope • Declaration • A syntactic construct of a language that associates information with a name • May be explicit or implicit • May occur several times for the same name in different parts of the program • The portion of the program for which the declaration of a variable applies is called the SCOPE of the that declaration • An occurrence of a name in a procedure is said to be local to it if it is in scope of a declaration within the procedure; otherwise, it is non-local. • Symbol table can be used to make this decision at compile time
Binding of Names • Is the association of a storage location with a name • When an environment associates storage location s, with a name x, then x is bound to s; • In programming language semantics • The term Environment refers to a function that maps a name to a storage location and • The term state refers to a function that maps a storage location to the value held there State Environment Name Value Storage
Declaration & Binding • While declaration is the static notion, Binding is the dynamic counterpart of the declaration STATIC NOTION DYNAMIC COUNTERPART Definition of a Procedure Activation of a Procedure Definition of a Name Binding of the Name Scope of a Declaration Lifetime of a Binding
Storage Allocation By a Compiler • The way a compiler organizes its storage & binds names is decided largely by answers to following Questions: • May procedures be recursive ? • What happens to the values of local names when control returns from an activation of a procedure ? • May a procedure refer to non-local names ? • How are parameters passed when a procedure is called ? • May procedures be passed as parameters? • May procedures be returned as results ? • May storage be allocated dynamically under program control ? • May storage be deallocated explicitly ?
Code Area Static data Control Stack Heap Storage Organization • Run time memory is sub-divided as follows: • Generated Target Code area (Size fixed & Known at compile time) • Data Objects ( ------’’ -------’’-----------) • A counterpart of Control Stack ( keeps track of procedure Activations) • Heap – a separate area that keeps all other information ( like free area for memalloc) • The size of Heap and control stack can vary dynamically.
Returned value • Actual Parameters • Optional Control link • Optional access link • Saved machine Status • Local Data • Temporaries Activation Record ( A.k.a. Frame ) • A contiguous block of storage that keeps Information needed to manage a single execution of a procedure • Has a collection of fields: • Returned value • Actual Parameters • Optional control link • Optional access link • Saved Machine Status • Local Data & • Temporaries Activation record • Not all languages nor all Compilers uses all these fields.
Use of Frame & its Components • Push Activities Record (A R ) of a procedure on the run-time stack when called and pop the A R off the stack on return. • Temporary values – evaluation of expressions • Local data field – name, type, relative address of storage, padding, packing etc. • Status of the m/c just before the proc is invoked. • Non-local data held in other ARs -Access Link • Optional control links to the caller. • Actual parameters to the called procedure. • Return a value to the called proc. • Returned value • Actual Parameters • Optional Control link • Optional access link • Saved machine Status • Local Data • Temporaries • Size of these fields decided at the time the procedure is called
Local Data Layout • Layout of data depends on : • The type of the data • The machine architecture ( its addressing constraints) The size of the data &
Storage Allocation Strategies • Different strategy is used for each of the three data areas namely code & data (1), stack (2) and Heap(3) • Static allocation • Lays out storage for all data objects at compile time. • Stack Allocation • Manages the run-time storage as a stack • Heap allocation • Allocates and de-allocates storage as needed at run-time from a data area known as a heap.
1.0 Static Allocation • Names are bound to storage as the program is compiled . ( No need for run time package) • Names are bound to the SAME locations every time the procedures are activated • Limitations:- • The size of the data objects and constraints must be known at compile time • Recursive procedures are restricted as the same bindings are used for local names • Data structures cannot be created dynamically
2.0 Stack Allocation • Storage organization based on the idea of a stack • Activation Records are pushed and popped as activations begin and end. • Storage for locals in each call of a procedure is embedded in the Activation Record for that call • The values of the locals are deleted when the activation ends as they are no longer required • Memory locations are by incrementing and decrementing the top by the size ‘a’ of the record.
Stack Allocation – illustrated A Rs ON THE STACK S s a : array r q ( 1,9) q (1,9) i : integer r i : integer q (5,9) q (1,3) p (1,9) p (1,9) q (1,3) i : integer p(1,3) q (2,3) q(2,1) q (2,1) i : integer q (2,3) i : integer p (1,3) p(1,3) q (1,0) q (3,3) q (3,3) i : integer q (1,0) i : integer p (1,3)
Calling Sequences • Implemented in target code for implementing procedure calls • A Call Sequence Allocates an activation record and enters information into its fields • A return Sequence restores the state of the machine so that calling procedure can continue execution • Calling sequences and activation records differ , even for implementations of the same language • The code in the calling sequence is often divided between the calling procedure ( caller) and the callee
The Call Sequence Actions • Top_sp – pointer to the end of machine status field
Parameters & returned value Control Link Link & Saved Status Temporaries & Local Data Parameters & returned value Control Link Link & Saved Status Temporaries & Local Data Division of tasks between caller & Callee CALLER’S AR CALLER’S RESPONSIBILITY CALLEE’S AR top_sp → CALLEE’S RESPONSIBILITY
Dangling references problem • Occurs when there is a reference to storage that has been de-allocated ( the value of de-allocated storage is undefined according to the semantics of most of the languages ) • Example: • main ( ); • { • int *p; • p = dangle ( ); • } • int *dangle ( ) • { • int i = 13 ; • return i; • }
3.0 Heap Allocation • Used when stack allocation fails • Stack allocation technique fails when • The values of local names must be retained when an activation ends • Called activation outlives the caller.! • Parcels out pieces of contiguous storage as needed for activation records or other objects • Pieces may be de-allocated in any order, • so over time, the heap will consist of alternate areas that are free and in use ( Fragmented)
S r q Control link Control link Control link Heap Allocation - illustrated s r q ( 1,9)
Access To Non-local names • The scope rules of the language decide the treatment to non-local names The most closely nested rule • The scope of a declaration in a block B includes B. • If a name x is not in B, then an occurrence of x in B is the scope of a declaration of x in an enclosing block B’ such that • B’ has a declaration of x and • B’ is the most closely nested to B than any other block with a similar declaration of x. • Block structure can be implemented using stack. (Block is a parameter-less procedure)
Scope of Variables • 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); • } DeclarationScope int a =0; 0 - 2 int b =0; 0 - 1 int b =1; 1- 3 int a =2; 2 int b =3; 3 0 2 1 3
Lexical Scope for Procedures • “Without nested” Procedures • Certain languages like C do not allow nesting of procedures ( procedure definition within another procedure) • If there is a non-local reference to a name ain some function, then amust be declared outside the function. int a [11]; readarray () {…. a….}; int partition (y,m) int y,x; { …. a…..}; quicksort (m,n) int m,n; {….}; main ( ) { … a.. }
“Without nested” Procedures - An Example back • program pass (input, output) ; • var m: integer • function f (n: integer) : integer ; • begin f := m + n end ( f ) ; • function g (n: integer) : integer ; • begin g := m * n end ( g ) ; • Procedure b ( function h (n:integer) : integer ) ; • begin write (h(2)) end ( h ) ; • begin • m := 0 ; • b ( f ) ; b ( g ) ; writeln • End ;
Program sort ( input , output ) Var a; array (0,,,10) of int ; x int Procedure readarray var i integer ; begin …. end ( readarray ) ; Procedure Exchange begin …. end ( exchange ) ; Procedure quicksort (….) ; var k, v integer ; function partition ( ……..) ; vaar i, j integer ; begin …. end ( partition ) ; begin …. end ( quicksort ) ; begin …. end ( sort ) ; Lexical Scope for Procedures • Nested Procedures: • Procedures can be defined within procedures ( ex: Pascal) • The notion of nesting depth of a procedure is used to implement lexical scope
Implementation • Lexical scope for nested procedures can be implemented by: • Adding a pointer called access link to each activation record. • If procedure p is nested immediately within q in the source text, • then the access link in an activation record for p points to the access link in the record for the most recent activation of q
Parameter Passing • When one procedure calls another, the usual method of communication between them is through : • Non-local names and • Parameters of the called procedure • Actual and formal parameters are associated to one another using techniques like : • Call by value • Call by Reference • Copy restore • Call by name & • Macro expansion
Parameter Passing • The different methods of parameter passing arise from differing interpretations of what an expression means: • Consider the assignment : a [ i ] := a[ j ] • Expression a[ j ] on RHS represents a value while • a [ i ] represents the storage location (or address) into which value of a [ j ] is placed • The decision of whether to use address or value is dependent on whether the expression appears to the • left (l-value) or right (r-value) of the assignment symbol • Different parameter passing techniques differ on whether a parameter represents an r-value or l-value or the text of the actual parameter itself
Parameter Passing techniques - I • Call by Value • Simplest technique where actual parameters are evaluated and their r-values are passed • Used in C and Pascal • IMPLEMENTATION: • Parameter treated like a local name storage allocated in the activation record of the Procedure • The caller evaluates the parameters and the r-value is placed in the space for formals • Note that the operation on formal parameters by callee do not affect values in the activation record of the caller
Call by Value Example • Program reference ( input, output) • var a, b : integer ; • procedure swap (var x, y: integer) • var temp : integer • begin • temp:= x; 7. x: = y; 8. y:= temp; • end; • begin • a : = 1 ; b:= 2 ; • swap ( a, b,) • writeln ( ‘a= ’, a); writeln ( ‘b= ’, b); • end.
Call by value Void main() { int a=10,b=20; printf(“Before swap \n”); printf(“%d %d”,a,b); swap(a,b) printf(“After swap \n”); printf(“%d %d”,a,b); } swap(int a,int b) { int temp; temp=a; a=b; b=temp; }
Parameter passing techniques – II • Call by reference ( A.k.a. Call-by-address) • Caller passes a pointer to the storage address of each location to the callee • Used in several languages ( Var parameters of Pascal) • IMPLEMENTATION: • If an actual parameter is a name or an expression having an l-value then the l-value itself is passed. • However, if the actual parameter be an expression that has no l-value, then the expression is evaluated in a new location, and the address of the location is passed.
Call by Reference Example • Program reference ( input, output) • var a, b : integer ; • procedure swap (var x, y: integer) • var temp : integer • Begin • temp:= x; 7. x: = y; 8. y:= temp; • end; • begin • a : = 1 ; b:= 2 ; • swap ( a, b,) • writeln ( ‘a= ’, a); writeln ( ‘b= ’, b); • End.
Call by Reference Void main() { int a=10,b=20; printf(“Before swap \n”); printf(“%d %d”,a,b); swap(&a,&b) printf(“After swap \n”); printf(“%d %d”,a,b); } swap(int *a,int *b) { int temp; temp=*a; *a=*b; *b=temp; }
Parameter passing techniques – III • Copy Restore ( A.k.a copy-in, copy-out / value-result) • A hybrid between call-by-value & call-by-reference • Used by some FORTRAN implementations • IMPLEMENTATION: • The r-values of the actual are passed as in call by value; • In addition the l-values of the actual parameters are determined before the call. • When control returns, the current r-values of the formal parameters are copied back into the l-values of the actuals using the l-value computed before the call
Copy – Restore Example • 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= ’, a); • end;
Parameter passing techniques – IV • Call by name • A procedure is treated as if it is a macro, • No values calculated or passed (the whole expression of the parameter is passed as a procedure without parameters, a thunk.) • Calculating the expression is performed by evaluating the thunk each time there is a reference to the parameter. • Ca have Unpleasant effects! • Found in Algol, Mathematica, Lazy functional language.( Primarily of theoretical interest ) • the body is substituted for the call in the caller, with actual parameters literally substituted for the formals. • The local names of the called procedures are kept distinct from the names of the calling procedure • The actual parameters are surrounded by parentheses
Why Error in Call by Name ? • The following happens in case of call by name: • x = text(’i’); • y = text(’a[i]’); • temp := i; (/* temp:=1 */) • i := a[i]; (/* i:=10 since a[i]=10 */) • a[i] := temp; (/* a[10]:=1 index out of bounds *)
Symbol Table • A data structure • Containing a record for each identifier • With fields for the attributes of the identifier • With a view to find the record quickly • Store and retrieve data fast • Keeps track of scope and binding information about names • Created at the beginning in lexical analysis, • other phases of compiler design such as Semantic analysis , code generators etc use unfilled fields
Symbol Table Management • Basically 2 mechanisms of maintaining this table • Linear lists: easier to implement but poor in performance if the nesting is deep and • Hash tables: with t greater programming efforts & space overhead. • It is useful to grow this table dynamically even at compile time but if the size of the table is fixed then it should be sufficiently large to handle any source of that language. • Information in the table is entered in various phases:- • Before LEX about keywords, particularly, if they are not reserved • LEX declaration gives info. about identifiers. & Attributes as and when they become available