Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct,...

68
Dynamic objects 1

Transcript of Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct,...

Page 1: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Dynamic objects

1

Page 2: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

The problem• l.next

• C: l is an instance of a struct, next is a field at a known offset

• Java: l is a reference to a known class, next is a field at a known offset

• Dynamic languages: l is a thing, lol, have fun

• Also Java: l is a reference to a known interface

2

Page 3: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Whence an object?

• Dynamically: A map of field names to values

• Remember: Values are blobs!

• Statically: A pointer to a data structure we define

3

Page 4: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Let’s build an objectstruct Object {

Map<string, blob> content;};

• This works, but it’s hard to make it efficient

• Observation:Many objects, few ways of making them

4

Page 5: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Idea

• Separate shape (common)from values (per-instance)

• Make shapes quick to check/compare

• Make related objects share their shape

• Optimize by caching shape (inline caching)

5

Page 6: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Step one: Objectstruct Object {

Shape *shape; // Map<string,int> + moreblob *content;

};

• Get/set: o->content[o->shape->get(field)]

• Add:• Reallocate content to get a new slot

• Create/find a new shape with the new field->slot

• Replace shape and content fields

6

Page 7: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Step two: Shapes

• Want similar objects to have same shape

• Same = Identical pointers

struct Shape {Map<string, int> slots;/* Shapes form a tree in which* steps are field additions */

Map<string, Shape*> transitions;};

7

Page 8: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Adding fields

• Keeping transitions in shapes meansshapes form a tree

• Add same fields → get same shape

8

Page 9: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

9

// l’s shape is 1, m’s shape is 1// i.e., they both have no fields[d] l.v = 42;

Page 10: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

10

// l’s shape is 1, m’s shape is 1// i.e., they both have no fields[d] l.v = 42;[h] allocate new shape (2)[h] add “v”→idx 0 shape 2[h] add “v”→shape 2 to shape 1[h] extend l->content with 42[h] l->shape = 2[d] l.n = m;

Page 11: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

11

// l’s shape is 1, m’s shape is 1// i.e., they both have no fields[d] l.v = 42;[h] allocate new shape (2)[h] add “v”→idx 0 shape 2[h] add “v”→shape 2 to shape 1[h] extend l->content with 42[h] l->shape = 2[d] l.n = m;[h] (same steps, shape 3)[d] m.v = 12; m.v = null;

Page 12: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

12

// l’s shape is 1, m’s shape is 1// i.e., they both have no fields[d] l.v = 42;[h] allocate new shape (2)[h] add “v”→idx 0 shape 2[h] add “v”→shape 2 to shape 1[h] extend l->content with 42[h] l->shape = 2[d] l.n = m;[h] (same steps, shape 3)[d] m.v = 12; m.n = null;[h] extend m->content,

m->shape = 3l->shape == m->shape

Page 13: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

13

// l’s shape is 3, m’s shape is 3// i.e., they both have v and n// o’s shape is 1[d] o.n = 42;

Page 14: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

14

// l’s shape is 3, m’s shape is 3// i.e., they both have v and n// o’s shape is 1[d] o.n = 42;[h] (same steps, new path)[d] o.v = 12;

Page 15: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

15

// l’s shape is 3, m’s shape is 3// i.e., they both have v and n// o’s shape is 1[d] o.n = 42;[h] (same steps, new path)[d] o.v = 12;[h] (same steps)

• Even though l and o have thesame fields, they have differentshapes because they wereadded through different paths

Page 16: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

16

SDyn

Page 17: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

17

// l’s shape is 3, m’s shape is 3// i.e., they both have v and nl->shape == m->shape

• If we cache l->shape,• check the shape at runtime,• generate code with field

locations burned in,• then pass in m,• it’ll be fast!

Page 18: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Inline caching

• Code for reading a field:

static Shape *cachedShape;static int cachedSlot;if (o->shape != cachedShape) {

cachedShape = o->shape;cachedSlot = o->shape->get(field);

}return o->content[cachedSlot];

18

Page 19: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Inline caching

• We can also cache shape transitions

• (If the cached shape doesn’t have the field, change both shape and content)

• Most VM’s implement a polymorphic inline cache

• ( Just means we cache multiple shape/slot pairs)

19

Page 20: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

20

SDyn

Page 21: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

GC backgroundManual memory management

Page 22: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory

Program + Static

Heap Free Stack

0x0 0xFFFF…

Page 23: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory

Program + Static

Heap Free Stack

0x0 0xFFFF…

StaticCreated bycompiler

Page 24: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory

Program + Static

Heap Free Stack

0x0 0xFFFF…

StaticCreated bycompiler

DynamicDefined bycompiler

Page 25: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory

Program + Static

Heap Free Stack

0x0 0xFFFF…

StaticCreated bycompiler

Controlledby runtime(GC or not)

DynamicDefined bycompiler

Page 26: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory

Program + Static

Heap Free Stack

0x0 0xFFFF…

StaticCreated bycompiler

Controlledby runtime(GC or not)

DynamicDefined bycompiler

Heap

Page 27: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Virtual memory

• Memory isn’t memory!

• Page tables give protection + control

• Not direct-to-RAM: Flexibility in allocation

Page 28: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Manual memory

• malloc(size):Returns pointer to size bytes of memory

• free(ptr):Frees space returned by malloc

• Presents the illusion of “objects”

• Internally, much more going on!

Page 29: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Page 30: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap

Allocated

Page 31: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

• mmap dumbly modifies page table:

• No memory of its own changes

• No object illusion

Dead space (no RWX)

Dead space (no RWX)

mmap

Allocated

Page 32: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap

Allocated

Page 33: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap

Allocated

Dead space (no RWX)

munmap

Allocated

Page 34: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

• Big chunks of free space

• Manager chooses size

• Manager must remember where

• Chicken and egg: Need static space for pointers to allocated space

Page 35: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Pools

• Keep track of memory in “pools”

• (Typically) Fixed size

• Maintained in list and/or (static) array

• Manager gives memory from pools

• Manager implements object illusion

Page 36: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap (manager)

Allocated

Dead space (no RWX)

malloc (user code)

AllocatedO

Page 37: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Object illusion

• User code: Pointer is sufficient info

• Manager: Need to know location and size

• Solution: Object headers

Page 38: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap (manager)

Allocated

Dead space (no RWX)

malloc (user code)

AllocatedOh

Page 39: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap (manager)

Allocated

Dead space (no RWX)

malloc (user code)

AllocatedOh

User code gets pointer to object

Page 40: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the managerDead space (no RWX)

Dead space (no RWX)

mmap (manager)

Allocated

Dead space (no RWX)

malloc (user code)

AllocatedOh

User code gets pointer to object

Manager always puts header before object

Page 41: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Object illusionstruct ObjectHeader {

size_t objectSize;

};

((struct ObjectHeader *) someObject)[-1].objectSize

Page 42: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Object illusionstruct ObjectHeader {

size_t objectSize;

};

((struct ObjectHeader *) someObject)[-1].objectSize

Must at leastremember size

Page 43: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

The simplest manager

• malloc(size):

Call mmap to allocate size + sizeof(ObjectHeader) bytes, put size in header, give pointer to space after header

• free(ptr):

Use object header to get size, call munmap

Page 44: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

The stupidest manager

• mmap works in pages (usu 4096 bytes)

• Most objects much smaller

• This is why we need pools!

Page 45: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Real management

• Manager must break pool into objects

• free can no longer return space to OS

• Manager must keep track of free’d space

• Concept of “free object”

Page 46: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)

malloc

OOO

Dead space (no RWX)

free

O F O

Page 47: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)

malloc

OOO

Dead space (no RWX)

free

O F O

Now owned by manager!Manager must remember all free objects

Page 48: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Free objects

• Keep on “free list”

• List head pointer at beginning of pool

• List next pointer in free objects

Page 49: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Free objectsstruct ObjectHeader {size_t objectSize;

};

struct FreeObject {struct FreeObject *next;

};

struct Pool {struct FreeObject *freeObjects;void *freeSpace;

};

Page 50: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Free objectsstruct ObjectHeader {size_t objectSize;

};

struct FreeObject {struct FreeObject *next;

};

struct Pool {struct FreeObject *freeObjects;void *freeSpace;

};

All objects, including freeones, have an object header,so don’t need size here!

Page 51: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Free objectsstruct ObjectHeader {size_t objectSize;

};

struct FreeObject {struct FreeObject *next;

};

struct Pool {struct FreeObject *freeObjects;void *freeSpace;

};

All objects, including freeones, have an object header,so don’t need size here!

This struct defines the static data in a pool:Remaining space is for allocated/free objects

Page 52: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)O OF

freeObjects

freeSpace

Page 53: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Allocation

• With free list:

• First try to find a suitable object1 on the free list

• If found, remove from free list and return

• If not found, allocate new object from free space

• If no free space, allocate new pool

1 This process is extremely complicated

Page 54: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)O OF

freeObjects

freeSpace

Page 55: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)O OO

freeSpace

Dead space (no RWX)O OF

freeObjects

freeSpace

Page 56: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)AllocatedO OF

freeObjects

O

Dead space (no RWX)O OF

freeObjects

freeSpace

Page 57: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Memory to the manager

Dead space (no RWX)O OF

freeObjects

freeSpace

New poolO

Dead space (no RWX)O OF

freeObjects

freeSpace

Page 58: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Considerations

• When object is allocated, manager has no pointer

• When object is free, not given back to OS

• Hardware, OS and manager all distinct

Page 59: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

The life of a pointerNothing

Mapped space

malloc (object created)

Pointer held by program

free (object disowned)

Free object

mmap (space allocated)

Memory manager

Program

Page 60: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

While owned by program,manager has no reference!

The life of a pointerNothing

Mapped space

malloc (object created)

Pointer held by program

free (object disowned)

Free object

mmap (space allocated)

Memory manager

Program

Page 61: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

While owned by program,manager has no reference!

The life of a pointerNothing

Mapped space

malloc (object created)

Pointer held by program

free (object disowned)

Free object

mmap (space allocated)

Memory manager

Program

Never returnedto OS!

Page 62: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Pools

• We may have multiple pools

• Free list per pool or global?

• If per pool: How to get from free(o) to pool?

• If global: Thread contention

Page 63: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Alignment

• Alignment allows magic with pointers!

• Remember: We can control where pools are mapped

Page 64: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Alignment

Dead space (no RWX)PoolO

0x01040000 0x01050000

0x0104B0C8 (e.g.)

Ex: Pools aligned to multiples of 0x00010000:

Page 65: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Alignment

Dead space (no RWX)PoolO

0x01040000 0x01050000

0x0104B0C8 (e.g.)

Ex: Pools aligned to multiples of 0x00010000:

“Pool mask”: 0xFFFF0000

Page 66: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Alignment

Dead space (no RWX)PoolO

0x01040000 0x01050000

0x0104B0C8 (e.g.)

Ex: Pools aligned to multiples of 0x00010000:

“Pool mask”: 0xFFFF0000(0x0104B0C8 & 0xFFFF0000) == 0x01040000

Page 67: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

Alignment

Dead space (no RWX)PoolO

0x01040000 0x01050000

0x0104B0C8 (e.g.)

Ex: Pools aligned to multiples of 0x00010000:

“Pool mask”: 0xFFFF0000(0x0104B0C8 & 0xFFFF0000) == 0x01040000

(struct Pool *) ((size_t) p & POOL_MASK)

Page 68: Dynamic objects - the.gregor.institute · The problem •l.next •C: lis an instance of a struct, nextis a field at a known offset •Java: lis a reference to a known class, nextis

void free(void *o) {

struct FreeObject *fo = (struct FreeObject *) o;

struct ObjectHeader *oh = &((struct ObjectHeader *) o)[-1];

struct Pool *p = (struct Pool *) ((size_t) o & POOL_MASK);

fo->next = p->freeList;

p->freeList = o;

}