Activation Records CS 671 February 7, 2008

Report
Activation Records
CS 671
February 7, 2008
The Compiler So Far
Lexical analysis
• Detects inputs with illegal tokens
Syntactic analysis
• Detects inputs with ill-formed parse trees
Semantic analysis
• Tries to catch all remaining errors
1
CS 671 – Spring 2008
Goals of a Semantic Analyzer
• Find remaining errors that would make
program invalid
– undefined variables, types
– type errors that can be caught statically
• Figure out useful information for later phases
– types of all expressions
– data layout
Terminology
Static checks – done by the compiler
Dynamic checks – done at run time
2
CS 671 – Spring 2008
Scoping
The scope rules of a language
• Determine which declaration of a named object
corresponds to each use of the object
C++ and Java use static scoping
• Mapping from uses to declarations at compile time
Lisp, APL, and Snobol use dynamic scoping
• Mapping from uses to declarations at run time
3
CS 671 – Spring 2008
Symbol Tables
Purpose
• keep track of names declared in the program
Symbol table entry
• associates a name with a set of attributes
– kind of name (variable, class, field, method, …)
– type (int, float, …)
– nesting level
– mem location (where will it be found at runtime)
4
CS 671 – Spring 2008
An Implementation
Symbol table can consist of:
• a hash table for all names, and
•a stack to keep track of scope
a \
a
x
y \
X
x \
x
5
CS 671 – Spring 2008
y
y
x
x
Scope
change
Type Systems
A language’s type system specifies which
operations are valid for which types
• A set of values
• A set of operations allowed on those values
The goal of type checking is to ensure that
operations are used with the correct types
• Enforces intended interpretation of values
Type inference is the process of filling in
missing type information
6
CS 671 – Spring 2008
Intermediate Code Generation
Source code
Lexical Analysis
lexical
errors
Syntactic Analysis
syntax
errors
Semantic Analysis
semantic
errors
tokens
AST
AST’
Intermediate Code Gen
IR
7
CS 671 – Spring 2008
Run time vs. Compile time
The compiler must generate code to handle
issues that arise at run time
• Representation of various data types
• Procedure linkage
• Storage organization
Big issue #1: Allow separate compilation
• Without it we can't build large systems
• Saves compile time
• Saves development time
• We must establish conventions on memory
layout, calling sequences, procedure entries and
exits, interfaces, etc.
8
CS 671 – Spring 2008
Activation Records
A procedure is a control abstraction
• it associates a name with a chunk of code
• that piece of code is regarded in terms of its
purpose and not of its implementation
A procedure creates its own name space
• It can declare local variables
• Local declarations may hide non-local ones
• Local names cannot be seen from outside
9
CS 671 – Spring 2008
Control Abstraction
Procedures must have a well defined call
mechanism
In many languages:
• a call creates an instance (activation) of the
procedure
• on exit, control returns to the call site, to the point
right after the call.
Use a call graph to see set of potential calls
10
CS 671 – Spring 2008
Handling Control Abstractions
Generated code must be able to
• preserve current state
– save variables that cannot be saved in registers
– save specific register values
• establish procedure environment on entry
– map actual to formal parameters
– create storage for locals
• restore previous state on exit
11
CS 671 – Spring 2008
Local Variables
•Functions have local variables
– created upon entry
•Several invocations may exist
•Each invocation has an instantiation
•Local variables are (often) destroyed upon
function exit
•Happens in a LIFO manner
•What else operates in a LIFO manner?
12
CS 671 – Spring 2008
Stack
•Last In, First Out (LIFO) data structure
main ()
{ a(0);
}
void a (int m)
{ b(1);
}
void b (int n)
{ c(2);
}
void c (int o)
{ d(3);
}
void d (int p)
{
}
13
stack
Stack Pointer
Stack Pointer
Stack Pointer
Stack Pointer
Stack Pointer
CS 671 – Spring 2008
Stack
grows
down
Stack Frames
Basic operations: push, pop
Happens too frequently!
Local variables can be pushed/popped in large
batches (on function entry/exit)
Instead, use a big array with a stack pointer
• Garbage beyond the end of the sp
A frame pointer indicates the start (for this
procedure)
14
CS 671 – Spring 2008
Stack Frames
Activation record or stack frame stores:
• local vars
• parameters
• return address
• temporaries
• (…etc)
fp
(Frame size not known until
late in the compilation process)
sp
15
CS 671 – Spring 2008
Arg n
…
Arg 2
Arg 1
Static link
Local vars
Ret address
Temporaries
Saved regs
Arg m
…
Arg 1
Static link
previous
frame
current
frame
next
frame
The Frame Pointer
Keeps track of the bottom of
the current activation record
g(…)
{
f(a1,…,an);
fp
}
•g is the caller
•f is the callee
sp
What if f calls two functions?
16
CS 671 – Spring 2008
Arg n
…
Arg 2
Arg 1
Static link
Local vars
Ret address
Temporaries
Saved regs
Arg m
…
Arg 1
Static link
g’s
frame
f’s
frame
next
frame
Stacks
Work languages with nested functions
• Functions declared inside other functions
• Inner functions can use outer function’s local vars
• Doesn’t happen in C
• Does happen in Pascal
Work with languages that support function
pointers
ML, Scheme have higher-order functions:
• nested functions AND
• functions as returnable values
(ML, Scheme cannot use stacks for local vars!)
17
CS 671 – Spring 2008
Handling Nested Procedures
Some languages allow nested procedures
• Example:
proc A() {
proc B () {
call C()
}
proc C() {
proc D() {
proc E() {
call B()
}
call E()
}
call D()
}
call B()
}
18
call sequence:
A
B
C
D
E
B
CS 671 – Spring 2008
Can B call C?
Can B call D?
Can B call E?
Can E access C's locals?
Can C access B's locals?
Handling Nested Procedures
In order to implement the "closest nested scope"
rule we need access to the frame of the lexically
enclosing procedure
Solution: static links
• Reference to the frame of the lexically enclosing
procedure
• Static chains of such links are created.
• How do we use them to access non-locals?
– The compiler knows the scope s of a variable
– The compiler knows the current scope t
– Follow s-t links
19
CS 671 – Spring 2008
Handling Nested Procedures
Setting the links:
• if callee is nested directly within caller
– set its static link to point to the caller's frame
pointer
proc A()
proc B()
• if callee has the same nesting level as the caller
– set its static link to point to wherever the
caller's static link points
proc A()
proc B()
20
CS 671 – Spring 2008
Activation Records
•Handling nested procedures
– We must keep a static link (vs. dynamic link)
•Registers vs. memory
– Registers are faster. Why?
add %eax,%ebx,%ecx
ld %ebx, 0[%fp]
ld %ecx, 4[%fp]
add %eax,%ebx,%ecx
21
CS 671 – Spring 2008
Cycles?
Registers
• Depending on the architecture, may have more
or fewer registers (typically 32)
%eax
%ah
%al
%ax
• Always faster to use registers
(remember the memory hierarchy)
• Want to keep local variables in registers
(when possible … why can’t we decide now?)
22
CS 671 – Spring 2008
Caller-save vs. Callee-save Registers
What if f wants to use a reg?
Who must save/restore that
register?
g(…) {
f(a1,…,an);
}
• If g saves before call, restores
after call caller-save
• If f saves before using a reg,
restores after callee-save
What are the tradeoffs?
23
CS 671 – Spring 2008
Arg n
…
Arg 2
Arg 1
Static link
Local vars
Ret address
Temporaries
Saved regs
Arg m
…
Arg 1
Static link
g’s
frame
fp
f’s
frame
sp
next
frame
Caller-save vs. Callee-save Registers
Usually – some registers are marked caller save and
some are marked callee save
e.g. MIPS: r16-23 callee save
all others caller save
Optimization – if g knows it will not need a value
after a call, it may put it in a caller-save register, but
not save it
Deciding on the register will be the task of the
register allocator (still a hot research area).
24
CS 671 – Spring 2008
Parameter Passing
By value
• actual parameter is copied
By reference
• address of actual parameter is stored
By value-result
• call by value, AND
• the values of the formal parameters are copied back
into the actual parameters
Typical Convention
– Usually 4 parameters placed in registers
– Rest on stack
– Why?
25
CS 671 – Spring 2008
Parameter Passing
We often put 4/6 parameters in registers …
What happens when we call another function?
•Leaf procedures – don’t call other procedures
•Non-leaf procedures may have dead variables
•Interprocedural register allocation
•Register windows
r32 r33 r34 r35 r32 r33
1 r34
1 r35
1 r32 r33 r34 r35 r32
A()
B()
C()
Outgoing args of A become incoming args to B
26
CS 671 – Spring 2008
Return Address
Return address - after f calls g, we must know
where to return
Old machines – return address always pushed on
the stack
Newer machines – return address is placed in a
special register (often called the link register %lr)
automatically during the call instruction
Non-leaf procedures must save %lr on the stack
Sidenote: Itanium has 8 “branch registers”
27
CS 671 – Spring 2008
Stack Maintenance
Calling sequence :
• code executed by the caller before and after a call
• code executed by the callee at the beginning
• code executed by the callee at the end
28
CS 671 – Spring 2008
Stack Maintenance
A typical calling sequence :
1. Caller assembles arguments and transfers
control
– evaluate arguments
– place arguments in stack frame and/or
registers
– save caller-saved registers
– save return address
– jump to callee's first instruction
29
CS 671 – Spring 2008
Stack Maintenance
A typical calling sequence :
2. Callee saves info on entry
– allocate memory for stack frame, update
stack pointer
– save callee-saved registers
– save old frame pointer
– update frame pointer
3. Callee executes
30
CS 671 – Spring 2008
Stack Maintenance
A typical calling sequence :
4. Callee restores info on exit and returns control
– place return value in appropriate location
– restore callee-saved registers
– restore frame pointer
– pop the stack frame
– jump to return address
5. Caller restores info
– restore caller-saved registers
31
CS 671 – Spring 2008
Handling Variable Storage
Static allocation
• object is allocated an address at compile time
• location is retained during execution
Stack allocation
• objects are allocated in LIFO order
Heap allocation
• objects may be allocated and deallocated at any
time.
32
CS 671 – Spring 2008
Review: Normal C Memory Management
A program’s address space
~ FFFF FFFF
contains 4 regions:
hex
stack
• stack: local variables, grows
•
•
•
33
downward
heap: space requested for
pointers via malloc() ; resizes
dynamically, grows upward
static data: variables
declared outside main, does
not grow or shrink
code: loaded when program
starts, does not change
CS 671 – Spring 2008
heap
static data
code
~ 0hex
Intel x86 C Memory Management
A C program’s x86 address
space :
• heap: space requested for
•
•
•
34
pointers via malloc(); resizes
dynamically, grows upward
static data: variables declared
outside main, does not grow or
shrink
code: loaded when program
starts, does not change
stack: local variables, grows
downward
CS 671 – Spring 2008
heap
static data
code
stack
Static Allocation
Objects that are allocated statically include:
• globals
• explicitly declared static variables
• instructions
• string literals
• compiler-generated tables used during run time
35
CS 671 – Spring 2008
Stack Allocation
Follows stack model for procedure activation
What can we determine at compile time?
• We cannot determine the address of the stack frame
• But we can determine the size of the stack frame
and the offsets of various objects within a frame
36
CS 671 – Spring 2008
Heap Allocation
Used for dynamically allocated/resized objects
Managed by special algorithms
General model
• maintain list of free blocks
• allocate block of appropriate size
• handle fragmentation
• handle garbage collection
37
CS 671 – Spring 2008
Summary
• Stack frames
– Keep track of run-time data
– Define the interface between procedures
• Both language and architectural features will
affect the stack frame layout and contents
• Started to see hints of the back-end optimizer,
register allocator, etc.
• Next week: Intermediate Representations
38
CS 671 – Spring 2008

similar documents