300 likes | 311 Views
Course Overview. PART I: overview material 1 Introduction 2 Language processors (tombstone diagrams, bootstrapping) 3 Architecture of a compiler PART II: inside a compiler 4 Syntax analysis 5 Contextual analysis 6 Runtime organization 7 Code generation PART III: conclusion
E N D
Course Overview PART I: overview material 1 Introduction 2 Language processors (tombstone diagrams, bootstrapping) 3Architecture of a compiler PART II: inside a compiler 4 Syntax analysis 5 Contextual analysis 6Runtime organization 7 Code generation PART III: conclusion • Interpretation 9 Review
Heap Storage Allocation • Data Representation: how to represent values of the source language on the target machine • Expression Evaluation: How to organize computing the values of expressions (taking care of intermediate results) • Stack Storage Allocation: How to organize storage for variables (considering lifetimes of global and local variables) • Routines: How to implement procedures, functions (and how to pass their parameters and return values) • Heap Storage Allocation: How to organize storage for variables (considering lifetimes of heap variables) • Object Orientation: Runtime organization for OO languages (how to handle classes, objects, methods)
Heap Storage Allocation • Recap: We have seen 2 storage allocation models so far: • static allocation • global variables • exist “forever” • stack allocation • local variables and arguments for procedures and functions • lifetime is from when procedure called until procedure returns • Next: Heap allocation. • Memory allocation is explicitly under the programmer’s control. • (C: malloc, C++ / Java / Pascal: new operation) Example: (Java) int[ ] nums = new int[sizeExpression];
Heap Storage Allocation Explicit versus Implicit Deallocation In explicit memory management, the program must explicitly call an operation to release memory back to the memory management system. In implicit memory management, heap memory is reclaimed automatically by a “garbage collector”. • Examples: • Implicit: Java, Scheme • Explicit: Pascal, C, C++ • To free heap memory a specific operation must be called. • Pascal ==> dispose • C ==> free • C++ ==> delete
Heap Storage Allocation Memory managers (both implicit as well as explicit) have been studied extensively by researchers. => Algorithms for fast allocation / deallocation of memory and low memory overhead for memory management administration. => There are many complicated, sophisticated, and interesting algorithms. We could dedicate an entire course to this topic alone! However, we only have time to look at memory management superficially. We will look at the kinds of algorithms/issues associated with explicit and implicit memory management.
Where to put the heap? The heap is an area of memory which is dynamically allocated. Like a stack, it may grow and shrink during runtime. (Unlike a stack, a heap is not LIFO => more complicated to manage.) In a typical programming language implementation, we will have both heap-allocated and stack-allocated memory that co-exist. Q: How do we allocate memory for both? A simple approach is to divide the available memory at the start of the program into two areas: stack and heap. Another question then arises: - How do we decide what portion to allocate for stack vs. heap? - Issue: if either one of the areas is full, then even though memory is available (in the other area) we will get out-of-memory errors. Q: Isn’t there a better way?
Where to put the heap? Q: Isn’t there a better way? A: Yes, there is an often used “trick”: let both stack and heap share the same memory area, but grow towards each other from opposite ends! SB Stack memory area ST Stack grows downward Heap can expand upward HT Heap memory area HB
How to keep track of free memory? Stack is LIFO allocation => ST moves up/down. Everything above ST is in use/allocated. Below ST is free memory. This part is easy! Heap is not LIFO, how to manage free space in the “middle” of the heap? SB Free HT Allocated Mixture of Allocated and Free space How to reuse? ST Free HB
Free Next Free Next Free Next How to keep track of free memory? How to manage free space in the “middle” of the heap? => Keep track of free blocks in a data structure: the “free list”. For example use a linked list pointing to the free blocks. freelist A freelist! Good idea! But where do we find the memory to store this data structure? HT HB
How to keep track of free memory? Q: Where do we find the memory to store a freelist data structure? A: Since the free blocks are not used for anything by the program => memory manager can use them for storing the freelist itself. HT HF free block size HF next free HB
Simple Explicit Memory Manager Algorithm We next consider a memory manager that is intended for a programming language with explicit deallocationof memory. Q: What operations does the memory management library provide? • Pointer malloc(int size); • Asks memory manager to find and allocate a block of specified size. Returns a pointer to beginning of that block. • void free(Pointer toFree, int size); • Called when a block toFree is released by the program and returned to the memory manager.
Simple Explicit Memory Manager Algorithm • Pointer malloc(int size) { • block = search the freelist until a block of at least size is found. • if (block is found) and (block.size == size) • delete block from free list. • return pointer to start of block. • else if (block found) and (block.size > size) • delete block from free list. • insert remainder of block into free list. • return pointer to start of block. • else // no block found • try to expand heap by size. • if (expansion was successful) then • return HT; • else generate out-of-memory error. • }
Simple Explicit Memory Manager Algorithm Pointer free(Pointer toFree, int size) { insert block(toFree,size) into the freelist } A bit more detail: • Pointer free(Pointer toFree, int size) { • toFree[0] = size; // size at offset 0 • toFree[1] = HF; // next pointer at offset 1 • HF = toFree; • } This algorithm is rather simplistic and has some rather big problems. Q: What are those problems? How could we fix them?
Fragmentation • One of the biggest problems with the simplistic algorithm is memory fragmentation. • blocks are split to create smaller blocks to fit the requested size. • blocks are never merged. • => Blocks will continually get smaller and smaller. Better algorithm merges released blocks with neighboring blocks that are free. => less fragmentation Q1: Analyze impact on the performance (time) for allocating and releasing blocks. Q2: Does this solve the fragmentation problem completely?
Heap Compaction To fight fragmentation, some memory management algorithms perform “heap compaction” once in a while. Q: Can compaction be done for all programming language implementations? before after HT a HF HT a b c b c d d HB HB
Complication with Explicit Memory Allocation • “Problems” with explicit memory allocation algorithms: • Two common, nasty kinds of bugs in programs using explicit memory management are • Memory leaks (garbage) • Dangling pointers Q1: What are memory leaks and dangling pointers? Q2: Is it true that there can be no memory leaks in a garbage-collected language? Q3: Is it true that there can be no dangling pointers in a garbage-collected language?
Automatic Storage Deallocation (Garbage Collection) Everybody probably knows what a garbage collector is. But here are two statements to make you think about what a garbage collector really does. • 1. A garbage collector provides the “illusion of infinite memory”. • A garbage collector predicts the future: it runs when “almost” • about to run out of memory. Next we consider one of the most often used garbage collection algorithms (if time permits).
Mark and Sweep Garbage Collection before gc mark as free phase SB SB ST ST HT HT X e e X d d c c X b b X X a a HB HB
SB ST HT X X e X X d b X X HB Mark and Sweep Garbage Collection mark as free phase mark reachable collect free SB SB ST ST HT HT X X X e e X X X d d c c X X b X b X X X X a a HB HB
Mark and Sweep Garbage Collection Algorithm pseudo code: void garbageCollect( ) { mark all heap variables as free for each frame in the stack scan(frame) for each heapvar that is still marked as free add heapvar to freelist } void scan(region) { for each pointer p in region if p points to region marked as free then mark region at p as reachable scan(region at p ) } Q: This algorithm is recursive. What do you think about that?
Object Orientation • Data Representation: how to represent values of the source language on the target machine • Expression Evaluation: How to organize computing the values of expressions (taking care of intermediate results) • Stack Storage Allocation: How to organize storage for variables (considering lifetimes of global and local variables) • Routines: How to implement procedures, functions (and how to pass their parameters and return values) • Heap Storage Allocation: How to organize storage for variables (considering lifetimes of heap variables) • Object Orientation: Runtime organization for OO languages (how to handle classes, objects, methods)
Runtime Organization for OO Languages What is this about? How to represent/implement object-oriented constructs such as objects, classes, methods, instance variables, and method calls. • Some definitions and relationships for these concepts: • An object is a group of instance variables to which a group of instance methods is attached. • An instance variable is a named component of a particular object. • An instance method is a named operation that is attached to a particular object and that is able to access that object’s instance variables. • A class is a family of objects with similar instance variables and identical methods.
Runtime Organization for OO Languages Objects are a lot like records and instance variables are a lot like fields. => The representation of objects is similar to that of a record. Methods are a lot like procedures/functions. => Implementation of methods is similar to routines. But there are differences: Objects have methods as well as instance variables, whereas records only have fields. The methods have to somehow know what object they are associated with (so that methods can access the object’s instance variables).
Example: Representation of a simple Java object Example 1: a simple Java object (no inheritance) class Point { int x, y; public Point(int x, int y) { this.x=x; this.y=y; } public void move(int dx, int dy) { x=x+dx; y=y+dy; } public float area( ) { return 0.0; } public float dist(Point other) { ... } } (1) (2) (3) (4)
class class xy xy 2 3 0 0 Example: Representation of a simple Java object Example: a simple Java object (no inheritance) new allocates an object in the heap Point p = new Point(2,3); Point q = new Point(0,0); p q Point class constructor(1) Pointmoveareadist method(2) method(3) method(4)
Inheritance Example 2: Points and other “shapes” abstract class Shape { int x, y; // “origin” of the shape public Shape(int x, int y) { this.x=x; this.y=y; } public void move(int dx, int dy) { x=x+dx; y=y+dy; } public abstract float area( ); public float dist(Shape other) { ... } } (S1) (S2) (S3)
Inheritance Example 2: Points and other “shapes” class Point extends Shape { public Point(int x, int y) { super(x,y); } public float area( ) { return 0.0; } } (P1) (P2)
Inheritance Example 2: Points and other “shapes” class Circle extends Shape { int r; public Circle(int x, int y, int r) { super(x,y); this.r = r; } public int radius( ) { return r; } public float area( ) { return 3.14 * r * r; } } (C1) (C2) (C3)
Inheritance Circle class constru(C1) Circlemoveareadist Shape class method(S2) Shapemoveareadist constru(S1) method(C3) method(S2) method(S3) method(C2) radius method(S3) Inherited from shape Point class Pointmoveareadist constru(P1) method(S2) Note the similar layout of each class object. Q: Why is that important? method(P2) method(S3) Q: Why don’t we need a pointer to the super-class in a class object?
class xy 2 3 Inheritance Shape[ ] s = new Shape[2];s[0] = new Point(2,3);s[1] = new Circle(4,5,6); s[0].x = ...;s[1].y = ...;float sumAreas = s[0].area( ) +s[1].area( ); s[0] s s[1] Point class class Circle class xyr 4 5 6 Note the similar layout between Point and Circle objects!