Kompilatorer och interpretatorer: Lecture 8

Note: This is an outline of what I intend to say on the lecture. It is not a definition of the course content, and it does not replace the textbook.

Today: Run-time environments. More symbol tables. Memory management.
ASU 7.1-7.3, 7.6. A paper about garbage collection: The Very Basics of Garbage Collection. KP chapter 4.

7 Run-Time Environments

What happens when the program is executed. Especially how names in the source program, like a variable called x, is translated to memory locations.

7.1 Source Language Issues

Some terms:

7.2 Storage organization

Subdivision of Run-Time Memory

ASU Fig. 7.7. Typical subdivision of run-time memory into code and data areas.

The stack is cheaper than the heap.

Activation records

ASU Fig. 7.8. A general activation record.

Or, use registers for actual parameters and for the returned value.

Compile-time layout of local data

All this is determined at compile-time. Each variable, such as the local variable i, has a fixed offset in the activation record. Fast to access, if a stack top pointer is kept in a register. The compiler generates code to access i as (e. g.) SP - 24.

7.3 Storage-allocation strategies

Static allocation

The compiler can decide the size and address of each data object. If activation records are static => recursion difficult (i. e., manage your own stack in a static data area). Example: FORTRAN.

(But don't learn the FORTRAN details in this chapter for the exam!)

Stack allocation

ASU Fig. 7.13. Downwards-growing stack allocation of activation records

Call sequence (Sw: anropskonventioner), return sequence

What should the caller (= the callING procedure) do, and what should the calle (=the callED procedure) do?
E. g., allocated the activation record, save registers.
Various call sequences exist.
In general, let the callED do as much as possible. (Just code generated for that once, instead of for each call to it!)

ASU Fig. 7.14. Division of tasks between caller and callee.

Example:

  1. The callER evaluates actuals. (And stores them?)
  2. The callER stores a return address and the old SP in the new activation record, and increments SP.
  3. The callED procedure saves registers and other status information.
  4. The callED procedure initializes local data + begins to execute.
The other way around when returning.

Variable-length data

Can be stored at the end of the activation record, with just pointers to it among the local variables.

Dangling references

Possible with malloc + bad free, but also with stack allocation. Example:
char* getstr() {
  char s[100];
  fgets(s, sizeof s, stdin);
  return s;
}

Heap allocation

malloc + free (or new + delete)

But also: activation records, if they have to be retained!

7.4 Access to non-local names

Can be skipped, but you may want to learn the difference between:

7.5 Parameter passing

Can be skipped, but you may want to learn the difference between:

7.6 Symbol tables

Very simple, from ASU chapter 2:
struct entry {
  char *lexptr; 
  int  token;    
};

#define SYMMAX 100
struct entry symtable[SYMMAX];
int lastentry = 0;
Additionally:

"Built during analysis, used during synthesis,"

We make a difference between:

Operations to handle scope in a block-structured language: We can use a stack! (Push each new scope.)
But hash tables are much more efficient.

Characters in a name

Skip this. Too low-level.

Hash tables

Skip (page 433-438). You're supposed to know about hash tables already.

Representing scope information

7.7 Language facilities for dynamic storage allocation

Skip. Read The Very Basics of Garbage Collection instead.

7.8 Dynamic storage allocation techniques

Skip. Read The Very Basics of Garbage Collection instead.

Garbage collection

The Very Basics of Garbage Collection

Terms:


Thomas Padron-McCarthy (Thomas.Padron-McCarthy@tech.oru.se) February 13, 2003