53
Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

  • View
    221

  • Download
    1

Embed Size (px)

Citation preview

Page 1: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

1

Theory of Compilation 236360

Erez Petrank

Lecture 9: Runtime (part 2); object oriented issues

Page 2: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Runtime Environment

• Code generated by the compiler to handle stuff that the programmer does not wish to handle.

• For example: file handling, memory management, synchronization (create threads, implement locks, etc.), runtime stack (activation records), etc.

• We discussed activation records and will next present an introduction to memory management.

Page 3: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

3

Dynamic Memory Management: Introduction

There is a course about this topic: 236780 “Algorithms for dynamic memory management”

Page 4: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

4

Static and Dynamic Variables

• Static variables are defined in a method and are allocated on the runtime stack, as explained in the first part of this lecture.

• Sometimes there is a need for allocation during the run. – E.g., when managing a linked-list whose size is not

predetermined.

• This is dynamic allocation. • In C, “malloc” allocates a space and “delete” says that the

program will not use this space anymore.

Ptr = malloc (256 bytes);/* Use ptr */Free (Ptr);

Page 5: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

5

Dynamic Memory Allocation

• In Java, “new” allocates an object for a given class. – President obama = new President

• But there is no instruction for manually deleting the object. It is automatically reclaimed by a garbage collector when the program “does not need it” anymore.

course c = new course(236360);c.class = “TAUB 2”;Faculty.add(c);

Page 6: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

6

Manual Vs. Automatic Memory Management

• A manual memory management lets the programmer decide when objects are deleted.

• A memory manager that lets a garbage collector delete objects is called automatic.

• Manual memory management creates severe debugging problems– Memory leaks,– Dangling pointers.

• In large projects where objects are shared between various components it is sometimes difficult to tell when an object is not needed anymore.

• Considered the BIG debugging problem of the 80’s• What is the main debugging problem today?

Page 7: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

7

Automatic Memory Reclamantion

• When the system “knows” the object will not be used anymore, it reclaims its space.

• Telling whether an object will be used after a given line of code is undecidable.

• Therefore, a conservative approximation is used. • An object is reclaimed when the program has “no way of

accessing it”. • Formally, when it is unreachable by a path of pointers from

the “root” pointers, to which the program has direct access. – Local variables, pointers on stack, global (class) pointers, JNI

pointers, etc.

• It is also possible to use code analysis to be more accurate sometimes.

Page 8: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

What’s good about automatic “garbage collection”?

© Erez Petrank 8

• Software engineering: – Relieves users of the book-keeping burden. – Stronger reliability, fewer bugs, faster debugging. – Code understandable and reliable. (Less interaction

between modules.)

• Security (Java):– Program never gets a pointer to “play with”.

Page 9: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

9

Importance

• Memory is the bottleneck in modern computation. – Time & energy (and space).

• Optimal allocation (even if all accesses are known in advance to the allocator) is NP-Complete (to even approximate).

• Must be done right for a program to run efficiently.

• Must be done right to ensure reliability.

Page 10: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

GC and languages

© Erez Petrank 10

• Sometimes it’s built in:– LISP, Java, C#.– The user cannot free an object.

• Sometimes it’s an added feature:– C, C++.– User can choose to free objects or not. The collector

frees all objects not freed by the user.

• Most modern languages are supported by garbage collection.

Page 11: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

© Erez Petrank 11

Most modern languages rely on GC

Source: “The Garbage Collection Handbook” by Richard Jones, Anthony Hosking, and Eliot Moss.

61

7

Page 12: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

What’s bad about automatic “garbage collection”?

© Erez Petrank 12

• It has a cost: – Old Lisp systems 40%.– Today’s Java program (if the collection is done “right”)

5-15%.

• Considered a major factor determining program efficiency.

• Techniques have evolved since the 60’s. We will only survey basic techniques.

Page 13: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

13

Garbage Collection Efficiency

• Overall collection time (percentage of running time).

• Pauses in program run. • Space overhead. • Cache Locality (efficiency and energy).

Page 14: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

14

Three classical algorithms

• Reference counting• Mark and sweep (and mark-compact)• Copying.

• The last two are also called tracing algorithms because they go over (trace) all reachable objects.

Page 15: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Reference counting [Collins 1960]

© Erez Petrank 15

• Recall that we would like to know if an object is reachable from the roots.

• Associate a reference count field with each object: how many pointers reference this object.

• When nothing points to an object, it can be deleted.

• Very simple, used in many systems.

Page 16: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Basic Reference Counting

© Erez Petrank 16

• Each object has an RC field, new objects get o.RC:=1.

• When p that points to o1 is modified to point to o2 we execute: o1.RC--, o2.RC++.

• if then o1.RC==0:– Delete o1.

– Decrement o.RC for all “children” of o1.

– Recursively delete objects whose RC is decremented to 0.

o1 o2

p

Page 17: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

A Problem: Cycles

© Erez Petrank 17

• The Reference counting algorithm does not reclaim cycles!

• Solution 1: ignore cycles, they do not appear frequently in modern programs.

• Solution 2: run tracing algorithms (that can reclaim cycles) infrequently.

• Solution 3: designated algorithms for cycle collection.

• Another problem for the naïve algorithm: requires a lot of synchronization in parallel programs.

• Advanced versions solve that.

Page 18: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

The Mark-and-Sweep Algorithm [McCarthy 1960]

© Erez Petrank 18

• Mark phase:– Start from roots and traverse all objects reachable by

a path of pointers. – Mark all traversed objects.

• Sweep phase:– Go over all objects in the heap. – Reclaim objects that are not marked.

Page 19: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

The Mark-Sweep algorithm

© Erez Petrank 19

• Traverse live objects & mark black. • White objects can be reclaimed.

sta

ckHeap

registers

Roots

Note! This is not the heap data structure!

Page 20: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Triggering

© Erez Petrank 20

New(A)=if free_list is empty

mark_sweep() if free_list is empty

return (“out-of-memory”)pointer = allocate(A)return (pointer)

Garbage collection is triggered by allocation.

Page 21: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Basic Algorithm

© Erez Petrank

21

mark_sweep()= for Ptr in Roots

mark(Ptr)sweep()

mark(Obj)=if mark_bit(Obj) == unmarked

mark_bit(Obj)=markedfor C in Children(Obj)

mark(C)

Sweep()=p = Heap_bottomwhile (p < Heap_top)

if (mark_bit(p) == unmarked) then free(p)else mark_bit(p) = unmarked; p=p+size(p)

Page 22: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Properties of Mark & Sweep

© Erez Petrank 22

• Most popular method today (at a more advanced form). • Simple.• Does not move objects, and so heap may fragment. • Complexity:

Mark phase: live objects (dominant phase) Sweep phase: heap size.

• Termination: each pointer traversed once. • Various engineering tricks are used to improve

performance.

Page 23: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

• During the run objects are allocated and reclaimed. • Gradually, the heap gets fragmented. • When space is too fragmented to allocate, a compaction

algorithm is used. • Move all live objects to the beginning of the heap and

update all pointers to reference the new locations. • Compaction is considered very costly and we usually

attempt to run it infrequently, or only partially.

Mark-Compact

23

The Heap

Page 24: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

24

An Example: The Compressor

• A simplistic presentation of the Compressor: • Go over the heap and compute for each live object where it

moves to – To the address that is the sum of live space before it in the

heap. – Save the new locations in a separate table.

• Go over the heap and for each object: – Move it to its new location– Update all its pointers.

• Why can’t we do it all in a single heap pass? • (In the full algorithm: succinct table, execute the first pass

quickly, and parallelization.)

Page 25: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

25

Mark Compact

• Important parameters of a compaction algorithm:– Keep order of objects?– Use extra space for compactor data structures?– How many heap passes? – Can it run in parallel on a multi-processor?

• We do not elaborate in this intro.

Page 26: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Copying garbage collection

© Erez Petrank 26

• Heap partitioned into two.• Part 1 takes all allocations.• Part 2 is reserved. • During GC, the collector traces all reachable

objects and copies them to the reserved part. • After copying the parts roles are reversed: • Allocation activity goes to part 2, which was

previously reserved. • Part 1, which was active, is reserved till next

collection.

1 2

Page 27: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Copying garbage collection

© Erez Petrank 27

Part I Part II

Roots

A

D

C

B

E

Page 28: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

The collection copies…

© Erez Petrank 28

Part I Part II

Roots

A

D

C

B

E

A C

Page 29: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Roots are updated; Part I reclaimed.

© Erez Petrank 29

Part I Part II

Roots

A C

Page 30: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Properties of Copying Collection

© Erez Petrank 30

• Compaction for free• Major disadvantage: half of the heap is not

used. • “Touch” only the live objects

– Good when most objects are dead. – Usually most new objects are dead, and so there are

methods that use a small space for young objects and collect this space using copying garbage collection.

Page 31: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

A very simplistic comparison

Copying

Mark & sweep

Reference Counting

Live objects

Size of heap (live objects)

Pointer updates + dead objects

Complexity

Half heap wasted

Bit/object + stack for DFS

Count/object + stack for DFS

Space overhead

For free Additional work Additional work

Compaction

long long Mostly short Pause time

Cycle collection

More issues

Page 32: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

32

Modern Memory Management

• Considers standard program properties. • Handle parallelism:

– Stop the program and collect in parallel on all available processors.

– Run collection concurrently with the program run.

• Cache consciousness. • Real-time.

Page 33: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Some terms to be remembered

© Erez Petrank 33

• Heap, objects

• Allocate, free (deallocate, delete, reclaim)

• Reachable, live, dead, unreachable

• Roots• Reference counting, mark and sweep,

copying, compaction, tracing algorithms

• Fragmentation

Page 34: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

34

Recap• Lexical analysis

– regular expressions identify tokens (“words”)

• Syntax analysis– context-free grammars identify the structure of the program

(“sentences”)

• Contextual (semantic) analysis– type checking defined via typing judgements– can be encoded via attribute grammars– Syntax directed translation

• Intermediate representation – many possible IRs; generation of intermediate representation;

3AC; backpatching

• Runtime: – services that are always there: function calls, memory

management, threads, etc.

Page 35: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

35

OO Issues

Page 36: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

36

Representing Data at Runtime

• Source language types– int, boolean, string, object types

• Target language types– Single bytes, integers, address representation

• Compiler should map source types to some combination of target types– Implement source types using target types

Page 37: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

37

Basic Types

• int, boolean, string, void• Arithmetic operations

– Addition, subtraction, multiplication, division, remainder

• Can be mapped directly to target language types and operations

Page 38: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

38

Pointer Types

• Represent addresses of source language data structures

• Usually implemented as an unsigned integer• Pointer dereferencing – retrieves pointed value

• May produce an error– Null pointer dereference – when is this error triggered?

Page 39: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

39

Object Types

• An object is a record with built in methods and some additional features.

• Basic operations– Field selection + read/write

• computing address of field, dereferencing address

– Copying• copy block (not Java) or field-by-field copying

– Method invocation• Identifying method to be called, calling it

• How does it look at runtime?

Page 40: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

40

Object Types

class Foo { int x; int y;

void rise() {…} void shine() {…}}

x

y

rise

shine

Compile time information

Runtime memory layout for object of class Foo

DispacthVectorPtr

Page 41: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

41

Field Selection

x

y

rise

shine

Compile time information

Runtime memory layout for object of class Foo

DispacthVectorPtrFoo f;int q;

q = f.x;

MOV f, %EBXMOV 4(%EBX), %EAXMOV %EAX, q

base pointer

field offset

from base pointer

Page 42: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

42

Object Types - Inheritance

x

y

rise

shine

Compile time information

Runtime memory layout for object of class Bar

twinkle

z

DispacthVectorPtr

class Foo { int x; int y;

void rise() {…} void shine() {…}}

class Bar extends Foo{ int z; void twinkle() {…}}

Page 43: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

43

Object Types - Polymorphism

class Foo { … void rise() {…} void shine() {…}}

x

y

Runtime memory layout for object of class Bar

class Bar extends Foo{ …}

z

class Main { void main() { Foo f = new Bar(); f.rise();}

f

Pointer to Bar

Pointer to Foo inside Bar

DVPtr

Page 44: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

44

Static & Dynamic Binding

• Which “rise” should is main() using? • Static binding: f is of type Foo and therefore it always refers

to Foo’s rise. • Dynamic binding: f points to a Bar object now, so it refers

to Bar’s rise.

class Foo { … void rise() {…} void shine() {…}}

class Bar extends Foo{ void rise() {…}}

class Main { void main() { Foo f = new Bar(); f.rise();}

Page 45: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

45

Typically, Dynamic Binding is used

• Finding the right method implementation at runtime according to object type

• Using the Dispatch Vector (a.k.a. Dispatch Table)

class Foo { … void rise() {…} void shine() {…}}

class Bar extends Foo{ void rise() {…}}

class Main { void main() { Foo f = new Bar(); f.rise();}

Page 46: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

46

Dispatch Vectors in Depth

• Vector contains addresses of methods• Indexed by method-id number• A method signature has the same id number for all subclasses

class Main { void main() { Foo f = new Bar(); f.rise();}

class Foo { … void rise() {…} void shine() {…}}

01

class Bar extends Foo{ void rise() {…}}

0

xyz

fPointer to Bar

Pointer to Foo inside BarDVPtr

shine

rise

shinerise

Dispatchvector for Bar

Methodcode

using Bar’s

dispatch table

Page 47: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

47

Dispatch Vectors in Depthclass Main { void main() { Foo f = new Foo(); f.rise();}

class Foo { … void rise() {…} void shine() {…}}

01

class Bar extends Foo{ void rise() {…}}

0

xy

f

Pointer to Foo

DVPtrshine

rise

shinerise

using Foo’s

dispatch table

Dispatchvector for Foo

Methodcode

Page 48: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

48

Representing dispatch tables

class A { void rise() {…} void shine() {…} static void foo() {…}}class B extends A { void rise() {…} void shine() {…} void twinkle() {…}}

# data section.data .align 4_DV_A: .long _A_rise .long _A_shine_DV_B: .long _B_rise .long _B_shine .long _B_twinkle

Page 49: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

Multiple Inheritance

49

supertyping convert_ptr_to_E_to_ptr_to_C(e) = e convert_ptr_to_E_to_ptr_to_D(e) = e + sizeof (class C)

subtyping convert_ptr_to_C_to_ptr_to_E(e) = c convert_ptr_to_D_to_ptr_to_E(e) = e - sizeof (class C)

class C { field c1; field c2; void m1() {…} void m2() {…}}class D { field d1; void m3() {…} void m4() {…}}class E extends C,D{ field e1; void m2() {…} void m4() {…} void m5() {…}}

c1c2

DVPtr

Pointer to E

Pointer to C inside EDVPtr

m2_C_E

m1_C_C

E-Object layout

Dispatchvector

d1e1

m4_D_E

m3_D_D

m5_E_EPointer to D inside E

Page 50: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

50

Runtime checks

• generate code for checking attempted illegal operations– Null pointer check– Array bounds check– Array allocation size check– Division by zero– …

• If check fails jump to error handler code that prints a message and gracefully exists program

Page 51: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

51

Null pointer check

# null pointer check cmp $0,%eax je labelNPE

labelNPE: push $strNPE # error message call __println push $1 # error code call __exit

Single generated handler for entire program

Page 52: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

52

Array bounds check

# array bounds check mov -4(%eax),%ebx # ebx = length mov $0,%ecx # ecx = index cmp %ecx,%ebx jle labelABE # ebx <= ecx ? cmp $0,%ecx jl labelABE # ecx < 0 ?

labelABE: push $strABE # error message call __println push $1 # error code call __exit

Single generated handler for entire program

Page 53: Theory of Compilation 236360 Erez Petrank Lecture 9: Runtime (part 2); object oriented issues 1

53

Array allocation size check

# array size check cmp $0,%eax # eax == array size jle labelASE # eax <= 0 ?

labelASE: push $strASE # error message call __println push $1 # error code call __exit

Single generated handler for entire program