How JavaScript Objects Are Implemented

50
How JavaScript Objects are Implemented Eddy Jean-Paul Bruel

description

How JavaScript Objects are Implemented

Transcript of How JavaScript Objects Are Implemented

Page 1: How JavaScript Objects Are Implemented

How JavaScript Objects are Implemented

Eddy Jean-Paul Bruel

Page 2: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 3: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 4: How JavaScript Objects Are Implemented

Properties• An object is a collection of named properties.

• Each property has the following attributes:

• [[Enumerable]] Whether the property will be enumerated by for-in.

• [[Configurable]] Whether the property can be deleted, or its attributes (other than [[Value]]) modified.

• Each property is either a data property or an accessor property.

Page 5: How JavaScript Objects Are Implemented

Data Properties

• A data property is a property that has the following attributes:

• [[Value]] The value of the property.

• [[Writable]] Whether the value of the property can be modified.

Page 6: How JavaScript Objects Are Implemented

Accessor Properties• An accessor property is a property that has

the following attributes:

• [[Get]] A function to access the value of the property.

• [[Set]] A function to modify the value of the property.

Page 7: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 8: How JavaScript Objects Are Implemented

Shapes and Slots• In SpiderMonkey, an object

consists of:

• A linked list of shapes.

• A vector of slots.

• Each shape stores the name and attributes of a property (except [[Value]]).

• Each slot stores the [[Value]] attribute of a property.

• Each shape contains an index into the slot vector.

Page 9: How JavaScript Objects Are Implemented

Shapes and Slots• In SpiderMonkey, an object

consists of:

• A linked list of shapes.

• A vector of slots.

• Each shape stores the name and attributes of a property (except [[Value]]).

• Each slot stores the [[Value]] attribute of a property.

• Each shape contains an index into the slot vector.

Page 10: How JavaScript Objects Are Implemented

Shape Trees• Because the [[Value]] attribute

is stored separately, shapes can be (partially) shared for a set of properties IF:

• they have the same name,

• AND they have the same attributes (except [[Value]]),

• AND they are defined in the same order.

• This leads to the notion of shape trees.

Page 11: How JavaScript Objects Are Implemented

Shape Trees• Because the [[Value]] attribute

is stored separately, shapes can be (partially) shared for a set of properties IF:

• they have the same name,

• AND they have the same attributes (except [[Value]]),

• AND they are defined in the same order.

• This leads to the notion of shape trees.

Page 12: How JavaScript Objects Are Implemented

Empty Shapes• Every object starts out with

an empty shape.

• Objects start out with the same empty shape IF:

• they have the same compartment (i.e. global),

• AND they have the same class,

• AND they have the same prototype.

Page 13: How JavaScript Objects Are Implemented

Empty Shapes• Every object starts out with

an empty shape.

• Objects start out with the same empty shape IF:

• they have the same compartment (i.e. global),

• AND they have the same class,

• AND they have the same prototype.

Page 14: How JavaScript Objects Are Implemented

Empty Shapes• Every object starts out with

an empty shape.

• Objects start out with the same empty shape IF:

• they have the same compartment (i.e. global),

• AND they have the same class,

• AND they have the same prototype.

Page 15: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 16: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 17: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 18: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 19: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 20: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 21: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 22: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 23: How JavaScript Objects Are Implemented

Adding Properties

• To add a property P to an object O:

1. IF the current shape of O has a child C that stores P:

1. Let S be C.

2. ELSE:

1. Let S be a new shape that stores P.

2. Insert S as a child of the current shape of O.

3. Set the current shape of O to S.

Page 24: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 25: How JavaScript Objects Are Implemented

Shape Lookup

• To find the shape S that stores a property P on an object O.

1. Let S be the current shape of O.

2. If S stores P, return S.

3. If S is an empty shape, throw.

4. Let S be the parent of S.

5. Go back to 1.

Page 26: How JavaScript Objects Are Implemented

Shape Lookup

• To find the shape S that stores a property P on an object O.

1. Let S be the current shape of O.

2. If S stores P, return S.

3. If S is an empty shape, throw.

4. Let S be the parent of S.

5. Go back to 1.

Page 27: How JavaScript Objects Are Implemented

Shape Tables• Finding a shape using linear lookup has

O(n) worst case performance.

• Associate a shape table with each shape S.

• Finding a shape using shape tables has O(1) expected performance.

• Only store a shape table at S IF:

• the number of searches starting at S exceeds MAX_LINEAR_SEARCHES,

• AND the number of ancestors of S exceeds MAX_ENTRIES.

• Shape tables are shared between objects.

Page 28: How JavaScript Objects Are Implemented

Shape Tables• Finding a shape using linear lookup has

O(n) worst case performance.

• Associate a shape table with each shape S.

• Finding a shape using shape tables has O(1) expected performance.

• Only store a shape table at S IF:

• the number of searches starting at S exceeds MAX_LINEAR_SEARCHES,

• AND the number of ancestors of S exceeds MAX_ENTRIES.

• Shape tables are shared between objects.

Page 29: How JavaScript Objects Are Implemented

Inline Caching• For simple property access (i.e.

O[P]) we only need P.[[Value]].

• To get P.[[Value]], we need to know slotIndex(P).

• slotIndex(P) can only change if we remove properties (we will get to this in a bit).

• If we remove properties, currentShape(O) changes as well.

• Avoid unnecessary shape lookups by caching slotIndex(P) for currentShape(O).

Page 30: How JavaScript Objects Are Implemented

Inline Caching1. IF currentShape(O) is NOT equal to cachedShape(O)

(cache miss):

1. Find the shape S that stores P.

2. Set cachedSlot(P) to S.slotIndex

3. Set cachedShape(O) to currentShape(O).

2. ELSE (cache hit):

1. Load the value of P from cachedSlot(P) in the slot vector of O.

Page 31: How JavaScript Objects Are Implemented

Inline Caching• The JIT generates code in which cachedShape(O) and cachedSlot(P)

are hardcoded.

• On a cache miss, the cached values are updated in place (by recompiling the function).

• This is known as inline caching:

Page 32: How JavaScript Objects Are Implemented

Inline Caching• The JIT generates code in which cachedShape(O) and cachedSlot(P)

are hardcoded.

• On a cache miss, the cached values are updated in place (by recompiling the function).

• This is known as inline caching:

cmp [aex + CURRENT_SHAPE], CACHED_SHAPE jne cache_miss mov aex, [aex + CACHED_SLOT]

Page 33: How JavaScript Objects Are Implemented

Inline Caching• Modern JITs are actually even smarter than this, and

can cache slotIndex(P) for multiple O’s with different shapes.

• This is known as polymorphic inline caching.

Page 34: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 35: How JavaScript Objects Are Implemented

Removing Properties• To remove a property P from

an object O:

1. Find the shape S that stores P.

2. IF S == currentShape(O):

1. Set currentShape(O) to its parent.

3. ELSE:

1. Lazily fork the shape tree at the parent of S.

Page 36: How JavaScript Objects Are Implemented

Removing Properties• To remove a property P from

an object O:

1. Find the shape S that stores P.

2. IF S == currentShape(O):

1. Set currentShape(O) to its parent.

3. ELSE:

1. Lazily fork the shape tree at the parent of S.

Page 37: How JavaScript Objects Are Implemented

Removing Properties• To remove a property P from

an object O:

1. Find the shape S that stores P.

2. IF S == currentShape(O):

1. Set currentShape(O) to its parent.

3. ELSE:

1. Lazily fork the shape tree at the parent of S.

Page 38: How JavaScript Objects Are Implemented

Removing Properties• To remove a property P from

an object O:

1. Find the shape S that stores P.

2. IF S == currentShape(O):

1. Set currentShape(O) to its parent.

3. ELSE:

1. Lazily fork the shape tree at the parent of S.

Page 39: How JavaScript Objects Are Implemented

Dictionary Mode• Lazily forking the

property tree has O(n2) worst case performance.

• Instead, copy the entire shape tree, eliminating sharing altogether.

• This is known as dictionary mode.

Page 40: How JavaScript Objects Are Implemented

Dictionary Mode• Lazily forking the

property tree has O(n2) worst case performance.

• Instead, copy the entire shape tree, eliminating sharing altogether.

• This is known as dictionary mode.

Page 41: How JavaScript Objects Are Implemented

Dictionary Mode• Dictionary mode eliminates sharing, and is thus best

avoided.

• What you shouldn’t do:

• Deleting a non-last property.

• Changing the attributes of a non-last property.

• However:

• Setting a non-last property to undefined is ok.

• If the property is the last property, you’re also ok.

Page 42: How JavaScript Objects Are Implemented

Overview• How objects are specified

• How objects are represented

• Object operations:

• Adding properties

• Finding properties

• Removing properties

• Arrays and elements

Page 43: How JavaScript Objects Are Implemented

Elements

• A property name P is an array index IF:

• ToString(ToUint32(P)) == P,

• and ToUInt32(P) != 232 - 1.

• A property is an element IF its name is an array index.

Page 44: How JavaScript Objects Are Implemented

Arrays• Arrays store elements

in a separate slot vector, using the array index as the slot index.

• This is why properties are enumerated in insertion order, but elements are not.

Page 45: How JavaScript Objects Are Implemented

Arrays• Arrays store elements

in a separate slot vector, using the array index as the slot index.

• This is why properties are enumerated in insertion order, but elements are not.

Page 46: How JavaScript Objects Are Implemented

Array Holes

• Removing a non-last element replaces its value with an array hole.

• A sparse array is an array with one or more holes in it.

Page 47: How JavaScript Objects Are Implemented

Array Holes

• Removing a non-last element replaces its value with an array hole.

• A sparse array is an array with one or more holes in it.

Page 48: How JavaScript Objects Are Implemented

Sparse Elements• Attributes are stored on

shapes. Because elements don’t have shapes, they can’t have non-default attributes.

• Changing the attributes of an element replaces it with a property.

• Such properties are known as sparse elements.

• In an object, all elements are sparse.

Page 49: How JavaScript Objects Are Implemented

Sparse Elements• Attributes are stored on

shapes. Because elements don’t have shapes, they can’t have non-default attributes.

• Changing the attributes of an element replaces it with a property.

• Such properties are known as sparse elements.

• In an object, all elements are sparse.

Page 50: How JavaScript Objects Are Implemented

Thanks for Listening!Any questions?