Runtime Environments

Similar documents
Names, Scope, and Bindings

Names, Scope, and Bindings

Names, Scope, and Bindings

Names, Scope, and Bindings

The C Language COMS W Prof. Stephen A. Edwards Fall 2002 Columbia University Department of Computer Science

Generating Code and Running Programs

CS 536 Introduction to Programming Languages and Compilers Charles N. Fischer Lecture 11

CMSC 330: Organization of Programming Languages

CMSC 330: Organization of Programming Languages. Memory Management and Garbage Collection

CMSC 330: Organization of Programming Languages

CS61C : Machine Structures

Motivation for Dynamic Memory. Dynamic Memory Allocation. Stack Organization. Stack Discussion. Questions answered in this lecture:

Run-Time Environments/Garbage Collection

Run-time Environments

Run-time Environments

Dynamic Memory Management

Project. there are a couple of 3 person teams. a new drop with new type checking is coming. regroup or see me or forever hold your peace

6.172 Performance Engineering of Software Systems Spring Lecture 9. P after. Figure 1: A diagram of the stack (Image by MIT OpenCourseWare.

Memory Allocation. Static Allocation. Dynamic Allocation. Dynamic Storage Allocation. CS 414: Operating Systems Spring 2008

Advanced Programming & C++ Language

CS61C Midterm Review on C & Memory Management

Heap Management. Heap Allocation

Dynamic Memory Management! Goals of this Lecture!

Procedure and Object- Oriented Abstraction

A.Arpaci-Dusseau. Mapping from logical address space to physical address space. CS 537:Operating Systems lecture12.fm.2

Dynamic Memory Allocation

Dynamic Memory Allocation: Basic Concepts

Dynamic Memory Management

System Software Assignment 1 Runtime Support for Procedures

Review for the Final

CS356: Discussion #6 Assembly Procedures and Arrays. Marco Paolieri

Dynamic Memory Allocation: Basic Concepts

Introduction to Computer Systems /18 243, fall th Lecture, Oct. 22 th

! What do we care about? n Fast program execution. n Efficient memory usage. n Avoid memory fragmentation. n Maintain data locality

Run-time Environments -Part 3

Today. Dynamic Memory Allocation: Basic Concepts. Dynamic Memory Allocation. Dynamic Memory Allocation. malloc Example. The malloc Package

Acknowledgements These slides are based on Kathryn McKinley s slides on garbage collection as well as E Christopher Lewis s slides

Run-time Environments - 3

Automatic Garbage Collection

Chapter 10 Memory Model for Program Execution. Problem

Last week. Data on the stack is allocated automatically when we do a function call, and removed when we return

Language of the Machine Recursive functions

Run-time Environment

Binding and Storage. COMP 524: Programming Language Concepts Björn B. Brandenburg. The University of North Carolina at Chapel Hill

CS61C : Machine Structures

Machine Language Instructions Introduction. Instructions Words of a language understood by machine. Instruction set Vocabulary of the machine

CS61C : Machine Structures

CSE 509: Computer Security

Today. Dynamic Memory Allocation: Basic Concepts. Dynamic Memory Allocation. Dynamic Memory Allocation. malloc Example. The malloc Package

Memory Management. Chapter Fourteen Modern Programming Languages, 2nd ed. 1

Branch Addressing. Jump Addressing. Target Addressing Example. The University of Adelaide, School of Computer Science 28 September 2015

Name, Scope, and Binding. Outline [1]

Where We Are. Lexical Analysis. Syntax Analysis. IR Generation. IR Optimization. Code Generation. Machine Code. Optimization.

Lecture 13: Garbage Collection

Review! Lecture 5 C Memory Management !

Roadmap. Java: Assembly language: OS: Machine code: Computer system:

In Java we have the keyword null, which is the value of an uninitialized reference type

Lectures 13 & 14. memory management

Beyond Stack Smashing: Recent Advances in Exploiting. Jonathan Pincus(MSR) and Brandon Baker (MS)

Memory Management. Didactic Module 14 Programming Languages - EEL670 1

MIPS Functions and Instruction Formats

Class Information ANNOUCEMENTS

G Programming Languages - Fall 2012

Memory: Overview. CS439: Principles of Computer Systems February 26, 2018

Deallocation Mechanisms. User-controlled Deallocation. Automatic Garbage Collection

Wednesday, October 15, 14. Functions

Announcements. My office hours are today in Gates 160 from 1PM-3PM. Programming Project 3 checkpoint due tomorrow night at 11:59PM.

CSE 504. Expression evaluation. Expression Evaluation, Runtime Environments. One possible semantics: Problem:

Structs and Alignment CSE 351 Spring

Memory Allocation I. CSE 351 Autumn Instructor: Justin Hsia

CS577 Modern Language Processors. Spring 2018 Lecture Garbage Collection

MIPS Programming. A basic rule is: try to be mechanical (that is, don't be "tricky") when you translate high-level code into assembler code.

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2015 Lecture 11

CS24: INTRODUCTION TO COMPUTING SYSTEMS. Spring 2018 Lecture 11

Heap Management portion of the store lives indefinitely until the program explicitly deletes it C++ and Java new Such objects are stored on a heap

G Programming Languages - Fall 2012

Numbers: positional notation. CS61C Machine Structures. Faux Midterm Review Jaein Jeong Cheng Tien Ee. www-inst.eecs.berkeley.

Final CSE 131B Spring 2005

CA Compiler Construction

CSE 504: Compilers. Expressions. R. Sekar

CSE 504: Compiler Design. Runtime Environments

Exploiting the Behavior of Generational Garbage Collector

Run-time Environments. Lecture 13. Prof. Alex Aiken Original Slides (Modified by Prof. Vijay Ganesh) Lecture 13

The C Language Prof. Stephen A. Edwards

ECE 2035 A Programming Hw/Sw Systems Fall problems, 8 pages Final Exam Solutions 9 December 2015

Procedures and Stacks

MIPS Functions and the Runtime Stack

Separate compilation. Topic 6: Runtime Environments p.1/21. CS 526 Topic 6: Runtime Environments The linkage convention

! What is main memory? ! What is static and dynamic allocation? ! What is segmentation? Maria Hybinette, UGA. High Address (0x7fffffff) !

Types and Static Semantic Analysis

CS 11 C track: lecture 5

Memory Allocation. Copyright : University of Illinois CS 241 Staff 1

Dynamic Memory Allocation

CPSC 213. Introduction to Computer Systems. Winter Session 2017, Term 2. Unit 1c Jan 24, 26, 29, 31, and Feb 2

Short Notes of CS201

Scope, Functions, and Storage Management

CS558 Programming Languages

Lecture Notes on Garbage Collection

Agenda. CSE P 501 Compilers. Java Implementation Overview. JVM Architecture. JVM Runtime Data Areas (1) JVM Data Types. CSE P 501 Su04 T-1

2. dead code elimination (declaration and initialization of z) 3. common subexpression elimination (temp1 = j + g + h)

Transcription:

Runtime Environments Stephen A. Edwards Columbia University Fall 2018

Storage Classes The Stack and Activation Records In-Memory Layout Issues The Heap Automatic Garbage Collection Shared Libraries and Dynamic Linking Objects and Inheritance Exceptions

Storage Classes

Storage Classes and Memory Layout Stack: objects created/destroyed in last-in, first-out order Heap: objects created/destroyed in any order; automatic garbage collection optional Static: objects allocated at compile time; persist throughout run Stack Heap Static Code High memory Stack pointer Program break Low memory

Static Objects class Example { public static final int a = 3; } public void hello() { System.out.println("Hello"); } Advantages Zero-cost memory management Often faster access (address a constant) No out-of-memory danger Examples Static class variable Code for hello method String constant Hello Information about the Example class Disadvantages Size and number must be known beforehand Wasteful if sharing is possible

The Stack and Activation Records

Stack-Allocated Objects Natural for supporting recursion. Idea: some objects persist from when a procedure is called to when it returns. Naturally implemented with a stack: linear array of memory that grows and shrinks at only one boundary. Each invocation of a procedure gets its own frame (activation record) where it stores its own local variables and bookkeeping information.

An Activation Record: The State Before Calling bar int foo(int a, int b) { int c, d; bar(1, 2, 3); } b a Return addr. Old frame ptr. Registers c d 3 2 1 From Caller Frame Ptr. Stack Ptr.

Recursive Fibonacci (Real C) int fib(int n) { } if (n<2) return 1; else return fib(n-1) + fib(n-2); (Assembly-like C) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } fib(3) fib(2) fib(1) fib(1) fib(0)

Executing fib(3) SP n = 3 int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; }

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 2 tmp2 = tmp3 = n = 2

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 2 tmp2 = tmp3 = n = 2 return address last frame pointer tmp1 = 1 tmp2 = tmp3 = n = 1

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 2 tmp2 = tmp3 = n = 2 return address last frame pointer tmp1 = 1 tmp2 = tmp3 = n = 1 return address last frame pointer tmp1 = 1 tmp2 = tmp3 =

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 2 tmp2 = tmp3 = n = 2 return address last frame pointer tmp1 = 0 tmp2 = 1 tmp3 = n = 0

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 2 tmp2 = tmp3 = n = 2 return address last frame pointer tmp1 = 0 tmp2 = 1 tmp3 = n = 0 return address last frame pointer tmp1 = 1 tmp2 = tmp3 =

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 2 tmp2 = tmp3 = n = 2 return address last frame pointer tmp1 = 2 tmp2 = 1 tmp3 = 1

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 1 tmp2 = 2 tmp3 = n = 1

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 1 tmp2 = 2 tmp3 = n = 1 return address last frame pointer tmp1 = 1 tmp2 = tmp3 =

Executing fib(3) int fib(int n) { int tmp1, tmp2, tmp3; tmp1 = n < 2; if (!tmp1) goto L1; return 1; L1: tmp1 = n - 1; tmp2 = fib(tmp1); L2: tmp1 = n - 2; tmp3 = fib(tmp1); L3: tmp1 = tmp2 + tmp3; return tmp1; } FP SP n = 3 return address last frame pointer tmp1 = 3 result tmp2 = 2 tmp3 = 1

Allocating Fixed-Size Arrays Local arrays with fixed size are easy to stack. void foo() { int a; int b[10]; int c; } return address a b[9] FP. b[0] c FP 48

Allocating Variable-Sized Arrays Variable-sized local arrays aren t as easy. void foo(int n) { int a; int b[n]; int c; } return address a b[n-1] FP. b[0] c FP? Doesn t work: generated code expects a fixed offset for c. Even worse for multi-dimensional arrays.

Allocating Variable-Sized Arrays As always: add a level of indirection void foo(int n) { int a; int b[n]; int c; } return address FP a b-ptr c b[n-1]. b[0] Variables remain constant offset from frame pointer.

Nesting Function Definitions let articles words = let report w = let count = List.length (List.filter ((=) w) words) in w ^ ": " ^ string_of_int count in String.concat ", " (List.map report ["a"; "the"]) in articles ["the"; "plt"; "class"; "is"; "a"; "pain"; "in"; "the"; "butt"] let count words w = List.length (List.filter ((=) w) words) in let report words w = w ^ ": " ^ string_of_int (count words w) in let articles words = String.concat ", " (List.map (report words) ["a"; "the"]) in articles ["the"; "plt"; "class"; "is"; "a"; "pain"; "in"; "the"; "butt"] Produces a: 1, the: 2

Implementing Nested Functions with Access Links let a x s = a: (access link) x = 5 s = 42 let b y = let c z = z + s in let d w = c (w+1) in d (y+1) in (* b *) let e q = b (q+1) in e (x+1) (* a *) What does a 5 42 give?

Implementing Nested Functions with Access Links let a x s = let b y = let c z = z + s in a: e: (access link) x = 5 s = 42 (access link) q = 6 let d w = c (w+1) in d (y+1) in (* b *) let e q = b (q+1) in e (x+1) (* a *) What does a 5 42 give?

Implementing Nested Functions with Access Links let a x s = let b y = let c z = z + s in let d w = c (w+1) in d (y+1) in (* b *) a: e: b: (access link) x = 5 s = 42 (access link) q = 6 (access link) y = 7 let e q = b (q+1) in e (x+1) (* a *) What does a 5 42 give?

Implementing Nested Functions with Access Links let a x s = let b y = let c z = z + s in let d w = c (w+1) in d (y+1) in (* b *) let e q = b (q+1) in e (x+1) (* a *) a: e: b: d: (access link) x = 5 s = 42 (access link) q = 6 (access link) y = 7 (access link) w = 8 What does a 5 42 give?

Implementing Nested Functions with Access Links let a x s = let b y = let c z = z + s in let d w = c (w+1) in d (y+1) in (* b *) let e q = b (q+1) in e (x+1) (* a *) What does a 5 42 give? a: e: b: d: c: (access link) x = 5 s = 42 (access link) q = 6 (access link) y = 7 (access link) w = 8 (access link) z = 9

In-Memory Layout Issues

Layout of Records and Unions Modern processors have byte-addressable memory. 0 1 2 3 The IBM 360 (c. 1964) helped to popularize byte-addressable memory. Many data types (integers, addresses, floating-point numbers) are wider than a byte. 16-bit integer: 1 0 32-bit integer: 3 2 1 0

Layout of Records and Unions Modern memory systems read data in 32-, 64-, or 128-bit chunks: 3 2 1 0 7 6 5 4 11 10 9 8 It is harder to read an unaligned value: two reads plus shifting 3 2 1 0 7 6 5 4 11 10 9 8 Reading an aligned 32-bit value is fast: a single operation. 3 2 1 0 7 6 5 4 11 10 9 8 6 5 4 3 SPARC and ARM prohibit unaligned accesses MIPS has special unaligned load/store instructions x86, 68k run more slowly with unaligned accesses

Padding To avoid unaligned accesses, the C compiler pads the layout of unions and records. Rules: Each n-byte object must start on a multiple of n bytes (no unaligned accesses). Any object containing an n-byte object must be of size mn for some integer m (aligned even when arrayed). struct padded { int x; /* 4 bytes */ char z; /* 1 byte */ short y; /* 2 bytes */ char w; /* 1 byte */ }; x x x x y y z w struct padded { char a; /* 1 byte */ short b; /* 2 bytes */ short c; /* 2 bytes */ }; b b a c c

Unions A C struct has a separate space for each field; a C union shares one space among all fields union intchar { int i; /* 4 bytes */ char c; /* 1 byte */ }; union twostructs { struct { char c; /* 1 byte */ int i; /* 4 bytes */ } a; struct { short s1; /* 2 bytes */ short s2; /* 2 bytes */ } b; }; i i i i/c c i i i i or s2 s2 s1 s1

Arrays Basic policy in C: an array is just one object after another in memory. int a[10]; a[0] a[0] a[0] a[0] a[1] a[1] a[1] a[1]. a[9] a[9] a[9] a[9] This is why you need padding at the end of structs. struct { int a; char c; } b[2]; a a a a c a a a a c b[0] b[1]

Arrays and Aggregate types The largest primitive type dictates the alignment struct { short a; short b; char c; } d[4]; b b a a a a c c b b b b a a a a c c b b d[0] d[1] d[2] d[3]

Arrays of Arrays char a[4]; a[3] a[2] a[1] a[0] char a[3][4]; a[0][3] a[0][2] a[0][1] a[0][0] a[1][3] a[1][2] a[1][1] a[1][0] a[2][3] a[2][2] a[2][1] a[2][0] a[0] a[1] a[2]

The Heap

Heap-Allocated Storage Static works when you know everything beforehand and always need it. Stack enables, but also requires, recursive behavior. A heap is a region of memory where blocks can be allocated and deallocated in any order. (These heaps are different than those in, e.g., heapsort)

Dynamic Storage Allocation in C struct point { int x, y; }; int play_with_points(int n) { int i; struct point *points; points = malloc(n * sizeof(struct point)); for ( i = 0 ; i < n ; i++ ) { points[i].x = random(); points[i].y = random(); } /* do something with the array */ free(points); }

Dynamic Storage Allocation

Dynamic Storage Allocation free( )

Dynamic Storage Allocation free( )

Dynamic Storage Allocation free( ) malloc( )

Dynamic Storage Allocation free( ) malloc( )

Dynamic Storage Allocation Rules: Each allocated block contiguous (no holes) Blocks stay fixed once allocated malloc() Find an area large enough for requested block Mark memory as allocated free() Mark the block as unallocated

Simple Dynamic Storage Allocation Maintaining information about free memory Simplest: Linked list The algorithm for locating a suitable block Simplest: First-fit The algorithm for freeing an allocated block Simplest: Coalesce adjacent free blocks

Simple Dynamic Storage Allocation S N S S N

Simple Dynamic Storage Allocation S N S S N malloc( )

Simple Dynamic Storage Allocation S N S S N malloc( ) S S N S S N

Simple Dynamic Storage Allocation S N S S N malloc( ) S S N S S N free( )

Simple Dynamic Storage Allocation S N S S N malloc( ) S S N S S N free( ) S S N

Dynamic Storage Allocation Many, many other approaches. Other fit algorithms Segregation of objects by size More clever data structures

Heap Variants Memory pools: Differently-managed heap areas Stack-based pool: only free whole pool at once Nice for build-once data structures Single-size-object pool: Fit, allocation, etc. much faster Good for object-oriented programs

Fragmentation malloc( ) seven times give free() four times gives malloc( )? Need more memory; can t use fragmented memory. Zebra Tapir

Fragmentation and Handles Standard CS solution: Add another layer of indirection. Always reference memory through handles. *a *b *c Pointers The original Macintosh did this to save memory. **a **b **c Handles

Fragmentation and Handles Standard CS solution: Add another layer of indirection. Always reference memory through handles. *a *b *c Pointers The original Macintosh did this to save memory. **a **b **c Handles

Automatic Garbage Collection

Automatic Garbage Collection Entrust the runtime system with freeing heap objects Now common: Java, C#, Javascript, Python, Ruby, OCaml and most functional languages Advantages Much easier for the programmer Greatly improves reliability: no memory leaks, double-freeing, or other memory management errors Disadvantages Slower, sometimes unpredictably so May consume more memory

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b 0 42, 17

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b a 1 42, 17

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b a 3 42, 17 0 1

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b a b 3 42, 17 1 1

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b 0 a b 3 42, 17 2 1 1 1, 2

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b c 1 a b 3 42, 17 2 1 1 1, 2

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b c 1 b 2 42, 17 2 1 1 1, 2

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b 0 b 2 42, 17 2 1 1 1, 2

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b b 2 42, 17 1 1 0 1, 2

Reference Counting What and when to free? Maintain count of references to each object Free when count reaches zero let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b b 2 42, 17 1 1

Issues with Reference Counting Circular structures defy reference counting: a b Neither is reachable, yet both have non-zero reference counts. High overhead (must update counts constantly), although incremental

Mark-and-Sweep What and when to free? Stop-the-world algorithm invoked when memory full Breadth-first-search marks all reachable memory All unmarked items freed let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b c a b 42, 17 1, 2

Mark-and-Sweep What and when to free? Stop-the-world algorithm invoked when memory full Breadth-first-search marks all reachable memory All unmarked items freed let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b b 42, 17 1, 2

Mark-and-Sweep What and when to free? Stop-the-world algorithm invoked when memory full Breadth-first-search marks all reachable memory All unmarked items freed let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b b 42, 17 1, 2

Mark-and-Sweep What and when to free? Stop-the-world algorithm invoked when memory full Breadth-first-search marks all reachable memory All unmarked items freed let a = (42, 17) in let b = [a;a] in let c = (1,2)::b in b b 42, 17

Mark-and-Sweep Mark-and-sweep is faster overall; may induce big pauses Mark-and-compact variant also moves or copies reachable objects to eliminate fragmentation Incremental garbage collectors try to avoid doing everything at once Most objects die young; generational garbage collectors segregate heap objects by age Parallel garbage collection tricky Real-time garbage collection tricky

Shared Libraries and Dynamic Linking

Shared Libraries and Dynamic Linking The 1980s GUI/WIMP revolution required many large libraries (the Athena widgets, Motif, etc.) Under a static linking model, each executable using a library gets a copy of that library s code. Address 0: libxaw.a libx11.a xeyes libxaw.a libx11.a xterm libxaw.a libx11.a xclock

Shared Libraries and Dynamic Linking The 1980s GUI/WIMP revolution required many large libraries (the Athena widgets, Motif, etc.) Under a static linking model, each executable using a library gets a copy of that library s code. Address 0: libxaw.a libx11.a xeyes libxaw.a libx11.a xterm libxaw.a libx11.a xclock Wasteful: running many GUI programs at once fills memory with nearly identical copies of each library. Something had to be done: another level of indirection.

Shared Libraries: First Attempt Most code makes assumptions about its location. First solution (early Unix System V R3) required each shared library to be located at a unique address: libxm.so libxaw.so libxaw.so libx11.so libx11.so libx11.so Address 0: xeyes xterm netscape

Shared Libraries: First Attempt Most code makes assumptions about its location. First solution (early Unix System V R3) required each shared library to be located at a unique address: Address 0: libxm.so libxaw.so libxaw.so libx11.so libx11.so libx11.so xeyes xterm netscape Obvious disadvantage: must ensure each new shared library located at a new address. Works fine if there are only a few libraries; tended to discourage their use.

Shared Libraries Problem fundamentally is that each program may need to see different libraries each at a different address. libxaw.so libx11.so xeyes libxaw.so libx11.so xterm libxm.so libx11.so netscape

Position-Independent Code Solution: Require the code for libraries to be position-independent. Make it so they can run anywhere in memory. As always, add another level of indirection: All branching is PC-relative All data must be addressed relative to a base register. All branching to and from this code must go through a jump table.

Position-Independent Code for bar() Normal unlinked code save %sp, -112, %sp sethi %hi(0), %o0 R_SPARC_HI22.bss mov %o0, %o0 R_SPARC_LO10.bss sethi %hi(0), %o1 R_SPARC_HI22 a mov %o1, %o1 R_SPARC_LO10 a call 14 R_SPARC_WDISP30 strcpy nop sethi %hi(0), %o0 R_SPARC_HI22.bss mov %o0, %o0 R_SPARC_LO10.bss call 24 R_SPARC_WDISP30 baz nop ret restore gcc -fpic -shared save %sp, -112, %sp sethi %hi(0x10000), %l7 call 8e0! add PC to %l7 add %l7, 0x198, %l7 ld [ %l7 + 0x20 ], %o0 ld [ %l7 + 0x24 ], %o1 call Actually just a stub 10a24! strcpy nop ld [ %l7 + 0x20 ], %o0 call nop ret restore call is PC-relative 10a3c! baz

Objects and Inheritance

Single Inheritance Simple: Add new fields to end of the object Fields in base class always at same offset in derived class (compiler never reorders) Consequence: Derived classes can never remove fields C++ class Shape { double x, y; }; class Box : Shape { double h, w; }; class Circle : Shape { double r; }; Equivalent C struct Shape { double x, y; }; struct Box { double x, y; double h, w; }; struct Circle { double x, y; double r; };

Virtual Functions class Shape { virtual void draw(); // Invoked by object s run-time class }; // not its compile-time type. class Line : public Shape { void draw(); } class Arc : public Shape { void draw(); }; Shape *s[10]; s[0] = new Line; s[1] = new Arc; s[0]->draw(); // Invoke Line::draw() s[1]->draw(); // Invoke Arc::draw()

Virtual Functions Trick: add to each object a pointer to the virtual table for its type, filled with pointers to the virtual functions. Like the objects themselves, the virtual table for each derived type begins identically. struct A { int x; virtual void Foo(); virtual void Bar(); }; struct B : A { int y; virtual void Foo(); virtual void Baz(); }; A a1; A a2; B b1; A s Vtbl A::Foo A::Bar a1 vptr x a2 vptr x B s Vtbl B::Foo A::Bar B::Baz b1 vptr x y

Exceptions

C++ s Exceptions struct Except {} ex; // This struct functions as an exception void top(void) { try { child(); } catch (Except e) { // throw sends control here printf("oops\n"); } } void child() { child2(); } void child2() { throw ex; // Pass control up to the catch block } 1 2 3

C s setjmp/longjmp: Idiosyncratic Exceptions #include <setjmp.h> jmp_buf closure; /* return address, stack & frame ptrs. */ void top(void) { switch ( setjmp(closure) ) { /* normal: store closure, return 0 */ /* longjmp jumps here, returns 1 */ } case 0: child(); /* unexceptional case */ break; case 1: break; /* longjmp(,1) called */ } void child() { child2(); } void child2() { longjmp(closure, 1); } 4

Implementing Exceptions One way: maintain a stack of exception handlers try { push(ex, Handler); // Push handler on stack child(); } catch (Ex e) { foo(); } void child() { child2(); } void child2() { throw ex; } child(); pop(); goto Exit; Handler: foo(); Exit: void child() { child2(); } void child2() { throw(ex); } // Normal termination // Jump over "catch" // Body of "catch" // Unroll stack; find handler Incurs overhead, even when no exceptions thrown

Implementing Exceptions with Tables Q: When an exception is thrown, where was the last try? A: Consult a table: relevant handler or pop for every PC 1 void foo() { Lines Action 2 3 try { 4 bar(); 5 } catch (Ex1 e) { 6 a(); 7 } 8 } 9 10 void bar() { 11 baz(); 12 } 13 14 void baz() { 15 16 try { 17 throw ex1; 18 } catch (Ex2 e) { 19 b(); 20 } 21 } 1 2 Pop stack 3 5 Handler @ 5 for Ex1 6 15 Pop stack 16 18 Handler @ 18 for Ex2 19 21 Pop stack