Activation Records Aslan Askarov aslan@cs.au.dk Revised from slides - - PowerPoint PPT Presentation

activation records
SMART_READER_LITE
LIVE PREVIEW

Activation Records Aslan Askarov aslan@cs.au.dk Revised from slides - - PowerPoint PPT Presentation

Compilation 2016 Activation Records Aslan Askarov aslan@cs.au.dk Revised from slides by E. Ernst (Abstract) computer organization Program memory } code segment contains program text size fixed prior to runtime data


slide-1
SLIDE 1

Compilation 2016

Activation Records

Aslan Askarov aslan@cs.au.dk
 
 
 Revised from slides by E. Ernst

slide-2
SLIDE 2

(Abstract) computer organization

  • Program memory
  • code segment – contains program text
  • data segment – contains static program

data (globals)

  • stack – for locals and function arguments
  • heap – for dynamically allocated memory

  • Processor registers
  • Operations for moving data between

registers/memory

}

size fixed prior to runtime

}

size changes at runtime

slide-3
SLIDE 3

Call stack of a program

Higher addresses in memory Low addresses in memory contiguous region in memory that the program can use the stack grows from higher memory addresses to low

  • nes (could be otherwise

depending on architecture) Purpose of the stack:

  • store local variables
  • pass arguments
  • store return values
  • save registers

stack limit – set by OS

slide-4
SLIDE 4

Call stack of a program

Higher addresses in memory Low addresses in memory contiguous region in memory that the program can use the stack grows from higher memory addresses to low

  • nes (could be otherwise

depending on architecture) Purpose of the stack:

  • store local variables
  • pass arguments
  • store return addresses
  • save registers

stack limit – set by OS

Q: what happens if we push past beyond stack limit?

slide-5
SLIDE 5

Stack frames

Function 1 Function 1 Function 1 Function 2 Function 2 Function 2 Function 2 Function 2 Function 3 Function 3 Function 3 Function 3

Function 1 calls Function 2 that calls Function 3 active functions, because they haven’t returned yet

stack manipulations by each of the functions

Idea: the maximum amount of memory that each function needs for its locals, temps, etc can be (usually) pre- computed by the compiler Let’s increase the stack by that much at once instead

  • f many small increases

Call the region of the stack corresponding to each active function that function’s stack frame (also called activation record)

slide-6
SLIDE 6

Stack frames

Function 1 Function 1 Function 1 Function 2 Function 2 Function 2 Function 2 Function 2 Function 3 Function 3 Function 3 Function 3

Function 1 calls Function 2 that calls Function 3 active functions, because they haven’t returned yet

stack manipulations by each of the functions

activation record (or stack frame) for Function 1 stack frame for Function 2 stack frame for Function 3

slide-7
SLIDE 7

Frame pointer and Stack pointer

activation record for Function 1 activation record for Function 2

Not allocated: garbage

FP SP Stack pointer (SP): points to the “top”

  • f the stack

Frame pointer (FP): the value of SP at the time the frame got activated

slide-8
SLIDE 8

Frame layout: calling conventions

  • Cross-language calls

important: using libraries

  • Reasonable to follow a

standard: ‘calling convention’

  • Specifies stack frame layout,

register usage, routine entry, exit code

  • Likely C bias

argument 2 argument 1 returnAddr localvar1 localvar2 … storedR1 … temp1 …

Not allocated: garbage

FP SP

slide-9
SLIDE 9

Typical frame layout

  • Fits RISC architectures (such as

MIPS) well

  • Note ‘staticLink’…
  • Consider offsets from FP and SP:

are all known at compile time?

  • FP could be virtual, if frame size is

fixed

(prev. frame) arg_k … arg_1 staticLink localVar_1 … localVar_m returnAddr temp_1 … temp_p saved_R1 … saved_Rt …

(args for next)

FP SP

slide-10
SLIDE 10

Textbook Tiger frame layout

  • Fits x86, with simple register

usage strategy

  • Worth noting
  • return address pushed

automatically by call instruction

  • FP non-virtual, always saved
  • SP adjusted at runtime:

arguments pushed

(prev. frame) arg_k … arg_1 staticLink saved_FP localVar_1 … localVar_m returnAddr temp_1 … temp_p

FP

  • ld FP

nextArg_k nextArg_2 nextArg_1

SP SP SP

slide-11
SLIDE 11

Textbook Tiger frame slots

saved_FP localVar_1 ... localVar_m temp_1 ... temp_p ... (args for next)

FP

SP

(prev.frame) ... arg_k ... arg_1 staticLink returnAddr

SP SP SP

  • ld FP

Memory[FP] Memory[FP-8*1] Memory[FP-who_cares] Memory[FP+8] Memory[saved_FP], Memory[FP+16] Memory[FP+8*(2+1)] Memory[FP+8*(2+k)] Memory[FP-8*m] Memory[FP-8*(m+1)] Memory[FP-8*(m+p)] Memory[staticLink]?

Top of frame: known early Bottom: known later

slide-12
SLIDE 12
  • Relative concepts: caller/callee frames, routines
  • Allocate new frame (same figure):
  • push FP
  • FP := SP
  • SP := SP - frameSize
  • If SP fixed, may replace FP by 


SP - frameSize (‘virtual’ FP)

The Frame Pointer

(prev.frame) ...

SP FP

slide-13
SLIDE 13

Saving Registers

  • Re: a frame/routine may be a caller or a callee
  • Roles for registers: ‘Caller-save’ vs. ‘callee-save’
  • E.g. on x86-64 System V ABI we have
  • RBP

, RBX, and R12–R15 are callee-save registers, i.e., preserved across function calls

  • “Don’t mess with R12-15” / “Don’t rely on others”
  • Scenario: Nice if value in R11 is dead before call
  • Scenario: Put long-lived value in r12 (think: loop!)
slide-14
SLIDE 14

Passing Parameters

  • Pre-1960: Use globals, no recursion
  • 1970’ies: Pass parameters on stack
  • Later: 4-6 parameters in registers, rest on stack
  • Experience: Few routines >6 parameters!
  • Our approach: System V ABI (different from textbook!)
  • 6 params in registers, the remaining on stack
slide-15
SLIDE 15

Why is register passing useful?!

localVar_1 ... localVar_m returnAddr ... saved_a1 ... staticLink (prev.frame) ... saved_Ri ... staticLink

  • Scenario:
  • Calling f(a1..an) which calls g(z)
  • As much as possible kept in registers
  • Tempting claim: “No difference!”
  • Concept: Leaf routines
  • How rare?
  • Most invocations are leaves!
  • May not even need stack frame

f frame localVar_1 ... g frame

slide-16
SLIDE 16
  • Return address not statically known (.. why?)
  • Solution: Store return address
  • Traditional approach: Push at call instruction
  • Alternatives: store in register at call instruction
  • Non-leaf routines still have to write to the stack

Managing Return Addresses

slide-17
SLIDE 17

example3.c from Aleph One tutorial

slide-18
SLIDE 18
  • Using registers a good default, may fail...
  • Address of variable taken (‘&’, pass-by-reference)
  • Variable used from nested function
  • Variable too large for register (use several?)
  • Pointer arithmetics used (C arrays)
  • Spilling

Forcing Memory Storage

slide-19
SLIDE 19

Static links: concept

  • The previous frame is not necessarily the one that

is lexically scoped

  • Record information about enclosing frames
  • Pass nearest enclosing frame as hidden

argument (static link)

  • Keep ‘display’: global array of currently nearest

frame at all nesting levels

  • Lambda lifting: lots of arguments
  • We use static links
slide-20
SLIDE 20

type tree = {key: string, left: tree, right: tree} function prettyprint(tree: tree): string = let var output := " " function write(s: string) =

  • utput := concat(output, s)

function show(n: int, t: tree) = let function indent(s: string) = ( for i:=1 to n do write(" ") ; output := concat(output,s) ; write("\n")) in if t=nil then indent(".") else ( indent(t.key) ; show(n+1, t.left) ; show(n+1, t.right)) end in show(0,tree);

  • utput

Static Links: Example Stack

[write] [indent] [show] [prettyprint] [show]

wanted saved FP

slide-21
SLIDE 21

type tree = {key: string, left: tree, right: tree} function prettyprint(tree: tree): string = let var output := " " function write(s: string) =

  • utput := concat(output, s)

function show(n: int, t: tree) = let function indent(s: string) = ( for i:=1 to n do write(" ") ; output := concat(output,s) ; write("\n")) in if t=nil then indent(".") else ( indent(t.key) ; show(n+1, t.left) ; show(n+1, t.right)) end in show(0,tree);

  • utput

Static Links: Example Stack

[write] [indent] [show] [prettyprint] [show]

wanted saved FP

static link

slide-22
SLIDE 22

type tree = {key: string, left: tree, right: tree} function prettyprint(tree: tree): string = let var output := " " function write(s: string) =

  • utput := concat(output, s)

function show(n: int, t: tree) = let function indent(s: string) = ( for i:=1 to n do write(" ") ; output := concat(output,s) ; write("\n")) in if t=nil then indent(".") else ( indent(t.key) ; show(n+1, t.left) ; show(n+1, t.right)) end in show(0,tree);

  • utput

Static Links: Call Nested

SL = FP Case “call nested”: Static link for show from prettyprint is the frame of prettyprint itself, etc. SL = FP

slide-23
SLIDE 23

type tree = {key: string, left: tree, right: tree} function prettyprint(tree: tree): string = let var output := " " function write(s: string) =

  • utput := concat(output, s)

function show(n: int, t: tree) = let function indent(s: string) = ( for i:=1 to n do write(" ") ; output := concat(output,s) ; write("\n")) in if t=nil then indent(".") else ( indent(t.key) ; show(n+1, t.left) ; show(n+1, t.right)) end in show(0,tree);

  • utput

Static Links: Call Same

Case “call same”: Static link for show from show is the given static link SL = SL

slide-24
SLIDE 24

type tree = {key: string, left: tree, right: tree} function prettyprint(tree: tree): string = let var output := " " function write(s: string) =

  • utput := concat(output, s)

function show(n: int, t: tree) = let function indent(s: string) = ( for i:=1 to n do write(" ") ; output := concat(output,s) ; write("\n")) in if t=nil then indent(".") else ( indent(t.key) ; show(n+1, t.left) ; show(n+1, t.right)) end in show(0,tree);

  • utput

Static Links: Call Less Nested

Case “call outer”: Static link for write from indent is found by following the static link twice SL = SL.SL

slide-25
SLIDE 25

Summary

  • Procedural abstraction requires LIFO discipline
  • Use stack — push/pop complete frame
  • Frame layout: Convention plus many considerations
  • Our Tiger frame layout: Heavily InFrame-ish
  • Concepts: caller/callee, -save registers, longevity
  • Benefits of using registers, forces against it
  • Static links: Purpose, computation
  • Tiger software Frame, Translate, Temp. Abstract

registers and addresses, environment update

slide-26
SLIDE 26

TODO

  • Code pointers