RUN-TIME STORAGE Chuen-Liang Chen Department of Computer Science and Information Engineering National Taiwan University Taipei, TAIWAN
Program layout (1/2) typical program layout each block can be allocated to a “segment” under segmented memory system operand stack is required for some computer; Its size can be determined at compile-time highest address heap space stack space have to check collision dynamic static data literal pool program code for library and separately compiled modules static added by linker/loader static data literal pool read only program code read only reserved locations eg. used by O.S lowest address
Program layout (2/2) for load-and-go compiler highest address static data and literal pool heap space stack space generated iteratively program code library modules reserved locations lowest address
Static allocation space is allocated in fixed location for the life-time of a program applicable only when the number and size of data objects is known at compile-time suitable for global variables literals (or put them on a separate “literal pool” ) the only choice for early language (e.g. without recursion) preferable to address a data object as (DataArea, Offset) and binding DataArea at link-time
Heap allocation space is allocated and freed at any time and in any order suitable for dynamic memory allocation/deallocation allocation -- in demand best-fit first-fit circular-first-fit QUIZ: comparison deallocation no deallocation (work for implementations with a large virtual memory) explicit deallocation implicit deallocation single reference reference count mark-and-sweep garbage collection [ + compaction] free-space representation -- bit map, linked list
Stack allocation (1/2) suitable for recursive call activation record (AR) -- data space required for a call push / pop, when “call” / “return” example -- procedure p(a:integer) is b: real; c: array (1..10) of real; d,e : array (1..N) of integer; begin b := c(a) * 2.51; end; 2.51 is stored in literal pool dope vector -- fixed size descriptor for dynamic array; containing size and bounds of array (determined at run-time) space for e determined at run-time space for d pointer to e pointer to d dope vector determined at compile-time c b a control information register Offset = 0
Stack allocation (2/2) when too many recursive calls Þ too many AR Þ too many registers solutions: display registers & static and dynamic chains QUIZ: coroutine? QUIZ: variable declaration within block?
Display registers (1/2) observation (by scoping rules) --at most one active scope for one static nesting level at any time example -- active scopes (display) of P1 R1 Q1 Q2 S1 S2 R2 P2 P3 Q3 R3 P() int a Q() int b R() int c S() int d P;a,Q,R;b,S;d P;a,Q,R;b,S P;a,Q,R;c P;a,Q,R program runtime stack R3: c 2 1 Q3: b, S 2 1 P3: a, Q, R 1 P2: a, Q, R 1 R2: c 2 1 S2: d 3 2 1 S1: d 3 2 1 Q2: b, S 2 1 Q1: b, S 2 1 R1: c 2 1 1 P1: a, Q, R
Display registers (2/2) strategy -- allocating one display register for one static nesting level have to be modified when routine call / return QUIZ: detailed implementation
Static and dynamic chains using one register only; point to uppermost AR static chain -- alternative implementation of a display dynamic chain -- list of AR entry on run-time stack, to restore activation register example -- runtime stack active scopes (display) of P1 R1 Q1 Q2 S1 S2 R2 P2 P3 Q3 R3 R3: c P1: a, Q, R Q1: b, S R1: c S2: d Q2: b, S R2: c P2: a, Q, R Q3: b, S S1: d P3: a, Q, R 1 2 3 activation register dynamic chain static chain
Advanced features formal procedure QUIZ: how?