Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Subroutines and Control Abstraction. 2 Control Abstraction Abstraction Abstraction associate a name N to a program part P associate a name N to a program.

Similar presentations


Presentation on theme: "1 Subroutines and Control Abstraction. 2 Control Abstraction Abstraction Abstraction associate a name N to a program part P associate a name N to a program."— Presentation transcript:

1 1 Subroutines and Control Abstraction

2 2 Control Abstraction Abstraction Abstraction associate a name N to a program part P associate a name N to a program part P name describes the purpose or function of P name describes the purpose or function of P we can use N instead of P (implementation) we can use N instead of P (implementation) Control abstraction Control abstraction P is a well-defined operation P is a well-defined operation Data abstraction Data abstraction P represents information (often with operations to access & modify that information) P represents information (often with operations to access & modify that information)

3 3 Subroutines Principal mechanism of control abstraction Principal mechanism of control abstraction subroutine performs some operation on behalf of a caller subroutine performs some operation on behalf of a caller caller waits for the subroutine to finish caller waits for the subroutine to finish subroutine may be parameterized subroutine may be parameterized caller passes arguments (actual parameters) caller passes arguments (actual parameters) influence the behavior of the subroutine influence the behavior of the subroutine pass data to operate with pass data to operate with arguments are mapped to subroutine’s formal parameters arguments are mapped to subroutine’s formal parameters subroutine may return a value subroutine may return a value functions & procedures functions & procedures

4 4 Chapter contents... Review of the stack layout Review of the stack layout Calling sequences Calling sequences maintaining the stack maintaining the stack static chains & display to access nonlocals static chains & display to access nonlocals subroutine inlining subroutine inlining closures closures implementation examples implementation examples Parameter passing Parameter passing mode determines mode determines how arguments are passed and how arguments are passed and how subroutine operations affect them how subroutine operations affect them conformant array parameters, named & default parameters conformant array parameters, named & default parameters variable number of arguments variable number of arguments function return mechanisms function return mechanisms

5 5...Chapter contents Generic subroutines and modules Generic subroutines and modules Exception handling Exception handling mechanism to ‘pop out’ of a nested context without returning mechanism to ‘pop out’ of a nested context without returning recovery happens in the calling context recovery happens in the calling context Coroutines Coroutines a control abstraction other than a subroutine a control abstraction other than a subroutine useful for iterators, simulation, server programs useful for iterators, simulation, server programs

6 6 Review of stack layout Stack frame / activation record Stack frame / activation record arguments, return values arguments, return values bookkeeping information bookkeeping information return address return address saved register values saved register values local variables, temporaries local variables, temporaries static part static part variable-sized part variable-sized part

7 7

8 8

9 9 Accessing stack data Hardware support Hardware support stack pointer register SP: top of the stack stack pointer register SP: top of the stack frame pointer register FP: address within the current frame frame pointer register FP: address within the current frame Objects of the frame are accessed Objects of the frame are accessed using FP and a static displacement (offset) or using FP and a static displacement (offset) or using address & dope vector (which are in the static part) using address & dope vector (which are in the static part) no variable-sized objects  all objects have a static offset  one can use SP instead of FP (and save one register) no variable-sized objects  all objects have a static offset  one can use SP instead of FP (and save one register) Variable-sized arguments? Variable-sized arguments? method 1 method 1 store below current frame store below current frame use address/dope vector in argument area use address/dope vector in argument area method 2 method 2 pass just the address (to caller object) & dope vector pass just the address (to caller object) & dope vector copy object to ‘normal’ variable-sized area when subroutine is entered copy object to ‘normal’ variable-sized area when subroutine is entered

10 10 Nested routines & static scoping Pascal, Modula, Ada Pascal, Modula, Ada Note: many voices against the need of these Note: many voices against the need of these development of object-oriented programming development of object-oriented programming C works just fine without them C works just fine without them Accessing non-local objects Accessing non-local objects maintain static chain in frames (next slide) maintain static chain in frames (next slide) each stack frame contains a static link each stack frame contains a static link reference to the frame of the last activation of the lexically enclosing subroutine reference to the frame of the last activation of the lexically enclosing subroutine by analogy, saved value of FP = dynamic link by analogy, saved value of FP = dynamic link reference to the frame of the caller reference to the frame of the caller used to reclaim stack data used to reclaim stack data may (or may not) be the same as the static link may (or may not) be the same as the static link

11 11

12 12 Example Figure slide -1 Figure slide -1 Call from a lexically surrounding routine Call from a lexically surrounding routine C is called from B C is called from B we know that B must be active (and has a frame in the stack) we know that B must be active (and has a frame in the stack) How else can C be called? How else can C be called? C gets visible only when control enters B C gets visible only when control enters B  C is visible only from B & D (and routines declared in C & D)  C is visible only from B & D (and routines declared in C & D)  whatever routine P calls C, it must have a frame in the stack  whatever routine P calls C, it must have a frame in the stack

13 13 Display Static chains may (in theory) be long Static chains may (in theory) be long accessing an object k levels out requires the dereferencing of k static links accessing an object k levels out requires the dereferencing of k static links  k+1 memory accesses  k+1 memory accesses Display / display table Display / display table static chain embedded into an array static chain embedded into an array an entry for each lexical depth of the program an entry for each lexical depth of the program Display[j] = FP of the last activation of a routine declared at depth j Display[j] = FP of the last activation of a routine declared at depth j Using display Using display caller nested i levels deep caller nested i levels deep object nested k levels out of caller object nested k levels out of caller take frame Display[i-k] & use (compile-time constant) offset take frame Display[i-k] & use (compile-time constant) offset

14 14

15 15 Display or static chain? Most programs are only 2 or 3 levels deep Most programs are only 2 or 3 levels deep static chains are short static chains are short If a non-local object X is used often If a non-local object X is used often address calculation (arithmetic expression) of the frame of X, say FX, appears often in the code address calculation (arithmetic expression) of the frame of X, say FX, appears often in the code  common subexpression optimization automatically loads FX to some register  dereferencing is done only once Cost of maintaining display Cost of maintaining display slightly higher than maintaining static links slightly higher than maintaining static links Closures Closures easy to represent with static links easy to represent with static links whole display has to be copied (if used) whole display has to be copied (if used) some optimizations are possible some optimizations are possible compilers that use a display have a limit on the depth of nesting compilers that use a display have a limit on the depth of nesting

16 16 Calling sequences... Maintenance of the call stack Maintenance of the call stack code immediately before & after a call code immediately before & after a call prologue: code at the beginning of a subroutine prologue: code at the beginning of a subroutine epilogue: code at the end of a subroutine epilogue: code at the end of a subroutine all above = ‘calling sequence’ all above = ‘calling sequence’ Tasks to do ‘on the way in’ Tasks to do ‘on the way in’ pass parameters pass parameters save return address save return address update program counter update program counter update stack pointer (to allocate space) update stack pointer (to allocate space) save registers (including the frame pointer) save registers (including the frame pointer) only those that are important and only those that are important and may be overwritten by the called routine (= callee) update frame pointer (to point to the new frame) update frame pointer (to point to the new frame) initialize local data objects initialize local data objects

17 17...Calling sequences Tasks to do ‘on the way out’ Tasks to do ‘on the way out’ pass return parameters & function values pass return parameters & function values finalize local objects finalize local objects deallocate frame (restore SP) deallocate frame (restore SP) restore other saved registers restore other saved registers restore program counter (PC) restore program counter (PC) Division of the labor Division of the labor some tasks can be done only by the caller some tasks can be done only by the caller passing parameters passing parameters in general, things that may be different for different calls most can be done by either one most can be done by either one the more work in the callee the less space we need for the code the more work in the callee the less space we need for the code

18 18 Saving registers Ideally, save only those that Ideally, save only those that are used by the caller and are used by the caller and are overwritten by the callee are overwritten by the callee hard to track in separate compilation hard to track in separate compilation Simpler solution Simpler solution caller saves all registers that are in use, or caller saves all registers that are in use, or callee saves all registers it will overwrite callee saves all registers it will overwrite Compromise Compromise divide (data) registers into ‘caller-saves’ & ‘callee saves’ divide (data) registers into ‘caller-saves’ & ‘callee saves’ callee can assume there is nothing of interest in caller-saves callee can assume there is nothing of interest in caller-saves caller can assume no callee destroys callee-saves registers caller can assume no callee destroys callee-saves registers compiler allocates compiler allocates callee-saves registers for long-term data callee-saves registers for long-term data caller-saves for temporary data caller-saves for temporary data  caller-saves are seldom saved at all (caller knows that they contain junk)  caller-saves are seldom saved at all (caller knows that they contain junk)

19 19 Maintaining static chain Caller’s responsibility Caller’s responsibility links depend on the lexical nesting depth of the caller links depend on the lexical nesting depth of the caller Standard approach Standard approach compute the static link of the callee compute the static link of the callee callee directly inside caller: own FP callee directly inside caller: own FP callee is k levels outward: follow k static links callee is k levels outward: follow k static links pass it as an extra parameter pass it as an extra parameter Maintaining displays Maintaining displays callee at level j  callee at level j  save Display[j] in the stack save Display[j] in the stack replace Display[j] with callee’s FP replace Display[j] with callee’s FP why does it work: page 433 why does it work: page 433 Leaf routines Leaf routines routines that make no subroutine calls routines that make no subroutine calls no need to update Display for these no need to update Display for these

20 20 Implementing closures Display scheme breaks for closures Display scheme breaks for closures use 2 entry points for each subroutine use 2 entry points for each subroutine normal call normal call via closure call via closure call save Display[1..j] into stack save Display[1..j] into stack replace those with ones stored in the closure replace those with ones stored in the closure separate return code for closure calls separate return code for closure calls restore Display[1..j] restore Display[1..j]

21 21 Cost of maintenance Static chains Static chains call: k >= 0 load instructions, 1 store call: k >= 0 load instructions, 1 store return: no extra operations return: no extra operations Display Display 1 load & 1 store in prologue 1 load & 1 store in prologue 1 load & 1 store in epilogue 1 load & 1 store in epilogue No work for leaf routines No work for leaf routines

22 22 Case study: C on MIPS Hardware support Hardware support ra: register containing return address ra: register containing return address jal: (jump and link) sets ra jal: (jump and link) sets ra sp, fp sp, fp Notes Notes a simple language on a simple machine a simple language on a simple machine all stack object sizes known  all stack object sizes known  separate fp is not strictly needed (sp suffices) separate fp is not strictly needed (sp suffices) GNU gcc uses it anyway GNU gcc uses it anyway uniformity (gcc is highly portable) uniformity (gcc is highly portable) makes it possible to allocate space dynamically from the stack (alloca library function) makes it possible to allocate space dynamically from the stack (alloca library function)

23 23 Stack frame... Example of a stack frame (slide +1) Example of a stack frame (slide +1) Argument passing Argument passing assembled at the top of the frame (using sp) assembled at the top of the frame (using sp) build area is large enough to hold the largest argument list build area is large enough to hold the largest argument list no need to ‘push’ in the traditional sense (space is already allocated and sp does not change) no need to ‘push’ in the traditional sense (space is already allocated and sp does not change) optimization optimization first 4 scalar arguments are passed in machine registers first 4 scalar arguments are passed in machine registers space is reserved in stack for all arguments space is reserved in stack for all arguments register arguments are saved to stack if needed register arguments are saved to stack if needed e.g. we must pass a pointer to the argument e.g. we must pass a pointer to the argument

24 24

25 25...Stack frame Allocate temporary space from stack Allocate temporary space from stack  sp grows, fp stays  sp grows, fp stays C: alloca library routine C: alloca library routine fast to implement, automatic reclaiming fast to implement, automatic reclaiming see slide +1 see slide +1 Languages with nested subroutines Languages with nested subroutines not C not C use some register to pass the static link (r2) use some register to pass the static link (r2)

26 26

27 27 Returning values Scalar values (and pointers) Scalar values (and pointers) use some register (r2, f0) use some register (r2, f0) Structures Structures store to a given memory address store to a given memory address address is passed in a ‘hidden’ register parameter (r4) address is passed in a ‘hidden’ register parameter (r4) possible cases possible cases x = foo(...)  address of x is passed to foo x = foo(...)  address of x is passed to foo p(...,foo(...),...) p(...,foo(...),...) pass an address to the build area (argument list of p) pass an address to the build area (argument list of p) overwrites arguments of foo but they are not in use when returning from foo overwrites arguments of foo but they are not in use when returning from foo x = foo(...).a + y  use temporary variables x = foo(...).a + y  use temporary variables

28 28 gcc calling sequence... Caller Caller save “caller-save” registers in temporary variables save “caller-save” registers in temporary variables only those whose value is still needed after the call only those whose value is still needed after the call put (up to 4) scalar arguments into registers put (up to 4) scalar arguments into registers put remaining arguments (if any) into the build area put remaining arguments (if any) into the build area perform jal instruction (sets ra & jumps) perform jal instruction (sets ra & jumps) Callee (prologue) Callee (prologue) subtract frame size from sp (stack grows downwards) subtract frame size from sp (stack grows downwards) note: argument list belongs to the caller’s frame note: argument list belongs to the caller’s frame save fp, ra (if not a leaf routine) save fp, ra (if not a leaf routine) save callee-save registers save callee-save registers only those whose values may change before returning only those whose values may change before returning

29 29...gcc calling sequence Callee (epilogue) Callee (epilogue) place return value (r2, f0, memory address) place return value (r2, f0, memory address) copy fp into sp (deallocate alloca space) copy fp into sp (deallocate alloca space) restore saved registers (using sp) restore saved registers (using sp) add frame size to sp (deallocate frame) add frame size to sp (deallocate frame) jump to ra jump to ra Caller (at return) Caller (at return) move return values to wherever needed move return values to wherever needed caller-save registers are restored lazily caller-save registers are restored lazily when values are needed for the first time when values are needed for the first time

30 30 Optimizations & debugging Optimizations Optimizations many parts of the calling sequence can be omitted many parts of the calling sequence can be omitted e.g. no caller-saves e.g. no caller-saves many leaf routines do not use the stack at all many leaf routines do not use the stack at all everything happens inside registers everything happens inside registers Debugger support Debugger support compiler places information in the symbol table compiler places information in the symbol table starting & ending address of routines starting & ending address of routines size of the frame size of the frame whether sp or fp is used for object access whether sp or fp is used for object access which register holds return address which register holds return address which registers are saved (callee-saves) which registers are saved (callee-saves)

31 31 Inline expansion Alternative to stack-based calling Alternative to stack-based calling Expand routine body at the place of the call Expand routine body at the place of the call avoids various overheads avoids various overheads space allocation space allocation branching to and from subroutine branching to and from subroutine saving and restoring registers (not always) saving and restoring registers (not always) code improvement possible ‘over routine boundaries’ code improvement possible ‘over routine boundaries’ Language design Language design compiler chooses which calls to expand compiler chooses which calls to expand C++: keyword inline C++: keyword inline only a suggestion to the compiler only a suggestion to the compiler Ada: compilation pragmas Ada: compilation pragmas pragma inline pragma inline

32 32 Inline expansion & macros In-line expansion In-line expansion just an implementation technique just an implementation technique semantic of the program is not touched semantic of the program is not touched Macros Macros side-effects in arguments are evaluated at each argument occurrence side-effects in arguments are evaluated at each argument occurrence #define MAX(a,b) ((a) > (b) ? (a) : (b)) MAX (x++, y++) only expressions can be used to ‘return’ values only expressions can be used to ‘return’ values  no loops etc can be used in macros  no loops etc can be used in macros

33 33 Inline expansion: discussion Code speed increases Code speed increases  programmers can use good programming style and still get good performance  programmers can use good programming style and still get good performance e.g. class member functions to access/update instance data e.g. class member functions to access/update instance data  inline expansion may be a necessity for o-o languages  inline expansion may be a necessity for o-o languages at least if we want programmers to write good programs at least if we want programmers to write good programs Code size increases Code size increases Recursive routines? Recursive routines? expand once expand once filter out the first special cases filter out the first special cases nested calls are compiled ‘normally’ nested calls are compiled ‘normally’ example case: hash table lookup example case: hash table lookup most chains in a table are only one element long most chains in a table are only one element long nested call is often avoided nested call is often avoided

34 34

35 35 Parameter passing Use of subroutine parameters Use of subroutine parameters control behavior control behavior provide data to operate on provide data to operate on parameters make subroutines more abstract parameters make subroutines more abstract Formal parameters Formal parameters names in the declaration of a subroutine names in the declaration of a subroutine Actual parameters, arguments Actual parameters, arguments variables & expressions in subroutine calls variables & expressions in subroutine calls

36 36 Section contents Parameter-passing modes Parameter-passing modes values, references & closures values, references & closures Additional mechanisms Additional mechanisms conformant array parameters conformant array parameters missing & default parameters missing & default parameters named parameters named parameters variable-length argument lists variable-length argument lists Returning values (from functions) Returning values (from functions)

37 37 Subroutine call notation Prefix Prefix most commonly used: p(a,b,c) most commonly used: p(a,b,c) Lisp: (p a b c) Lisp: (p a b c) Infix Infix functions specified to be ‘operators’ functions specified to be ‘operators’ infixr 8 tothe; (* exponentiation *) fun x tothe 0 = 1.0 | x tothe n = x * (x tothe (n-1)); (* assume n>= 0 *) Mixfix Mixfix Smalltalk: arguments & function name interleaved Smalltalk: arguments & function name interleaved Note on uniformity Note on uniformity Lisp & Smalltalk functions are like ‘standard’ control structures Lisp & Smalltalk functions are like ‘standard’ control structures  more natural to introduce ‘own’ control abstractions  more natural to introduce ‘own’ control abstractions if a > b then max := a else max := b;(* Pascal *) (if (> a b) (setf max a) (setf max b)); Lisp (a > b) ifTrue: [max b) ifTrue: [max <_a] ifFalse: [max<- b].”Smalltalk”

38 38 Parameter modes Semantic rules governing parameter passing Semantic rules governing parameter passing determine relationship between the actual & formal parameters determine relationship between the actual & formal parameters single set of rules that apply to all parameters single set of rules that apply to all parameters C, Fortran, ML, Lisp C, Fortran, ML, Lisp two or more sets of rules two or more sets of rules each corresponding to some mode each corresponding to some mode Pascal, Modulas, Ada Pascal, Modulas, Ada heavily influenced by implementation issues heavily influenced by implementation issues

39 39 Call by value & call by reference Example: global x, call p(x) Example: global x, call p(x) what is passed to p? what is passed to p? call by value: a copy of x call by value: a copy of x x & the copy are independent of each other x & the copy are independent of each other call by reference: the address of x call by reference: the address of x formal parameter is an alias for x formal parameter is an alias for x most languages require that ‘x’ must have an l- value most languages require that ‘x’ must have an l- value Fortran 90 makes one if it doesn’t Fortran 90 makes one if it doesn’t

40 40 Value model languages Pascal Pascal by value: default mode by value: default mode by reference by reference use keyword VAR in the formal parameter list use keyword VAR in the formal parameter list C all parameters are passed by value all parameters are passed by value exception: array is passed as a pointer exception: array is passed as a pointer aliases must be created explicitly declare a formal pointer parameter declare a formal pointer parameter use address operator on the actual parameter void swap (int *a, int *b) {int t = *a, *a = *b, *b = t;}... swap (&v1, &v2); Fortran Fortran all variables are passed by reference all variables are passed by reference

41 41 Reference model languages Actual parameter is already a reference Actual parameter is already a reference  sensible to define only a single passing mode  sensible to define only a single passing mode Clu: call by sharing Clu: call by sharing actual & formal parameter refer to the same object actual & formal parameter refer to the same object Implementation Implementation as an address  pass the address as an address  pass the address as a value (immutable objects)  copy value as a value (immutable objects)  copy value Java: primitive values are copied, class objects shared Java: primitive values are copied, class objects shared

42 42 Function returns restrictions on the types of objects that can be returned restrictions on the types of objects that can be returned Algol 60, Fortran: a scalar value Algol 60, Fortran: a scalar value Pascal, early Modula-2: scalar or pointer Pascal, early Modula-2: scalar or pointer Algol 68, Ada, C, some Pascal: composite type values Algol 68, Ada, C, some Pascal: composite type values Modula-3, Ada 95: a subroutine, implemented as a closure Modula-3, Ada 95: a subroutine, implemented as a closure Lisp, ML: closure Lisp, ML: closure

43 43 Function return syntax Lisp, ML, Algol 68 Lisp, ML, Algol 68 no distinction between statements and expressions no distinction between statements and expressions value of the function is the value of its body value of the function is the value of its body Algol 60, Fortran, Pascal Algol 60, Fortran, Pascal function := expression problems with nested declarations problems with nested declarations more recent languages more recent languages return expression immediate termination of the subroutine immediate termination of the subroutine if the function still has something to do, then place the return value into a temporary variable if the function still has something to do, then place the return value into a temporary variable rtn := expression... return rtn

44 44...Function return Fortran Fortran function name :=... return Ada example Ada example return expression return expression SR example SR example result of a function has its own name result of a function has its own name


Download ppt "1 Subroutines and Control Abstraction. 2 Control Abstraction Abstraction Abstraction associate a name N to a program part P associate a name N to a program."

Similar presentations


Ads by Google