Você está na página 1de 50

How JavaScript Objects

are Implemented
Eddy Jean-Paul Bruel
Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
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.
[[Congurable]]
Whether the property can be deleted, or its
attributes (other than [[Value]]) modied.
Each property is either a data property or an accessor
property.
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
modied.
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.
Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
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.
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.
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 dened in the
same order.
This leads to the notion of shape
trees.
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 dened in the
same order.
This leads to the notion of shape
trees.
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.
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.
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.
Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
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.
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.
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.
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.
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.
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.
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.
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.
Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
Shape Lookup

To nd 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.
Shape Lookup

To nd 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.
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.
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.
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).
Inline Caching
1. 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.
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:


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]
Inline Caching

Modern JITs are actually even smarter than this, and


can cache slotIndex(P) for multiple Os with different
shapes.

This is known as polymorphic inline caching.


Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
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.
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.
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.
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.
Dictionary Mode
Lazily forking the
property tree has
O(n
2
) worst case
performance.
Instead, copy the entire
shape tree, eliminating
sharing altogether.
This is known as
dictionary mode.
Dictionary Mode
Lazily forking the
property tree has
O(n
2
) worst case
performance.
Instead, copy the entire
shape tree, eliminating
sharing altogether.
This is known as
dictionary mode.
Dictionary Mode
Dictionary mode eliminates sharing, and is thus best
avoided.
What you shouldnt do:
Deleting a non-last property.
Changing the attributes of a non-last property.
However:
Setting a non-last property to undened is ok.
If the property is the last property, youre also ok.
Overview
How objects are specied
How objects are represented
Object operations:
Adding properties
Finding properties
Removing properties
Arrays and elements
Elements
A property name P is an array index IF:
ToString(ToUint32(P)) == P,
and ToUInt32(P) != 2
32
- 1.
A property is an element IF its name is an
array index.
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.
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.
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.
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.
Sparse Elements
Attributes are stored on
shapes. Because elements
dont have shapes, they cant
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.
Sparse Elements
Attributes are stored on
shapes. Because elements
dont have shapes, they cant
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.
Thanks for Listening!
Any questions?

Você também pode gostar