Objects currently only support a hash based backing storage. Schema based storage should be implemented too.
The idea of schema based storage is that storage is separated into two parts. The backing storage for the object itself becomes a simple array. Indexes into this array are determined by a schema. This schema is a hash that maps names to indexes.
Every time a new key is added to the object, a new schema is created. This new schema is a copy of the previous schema that maps the new name to the end of the array. These two schemas are then connected to each other using a migration step, so:
Every object starts out with an empty map, named schema0;
Key a is added to the map. This creates schema1 that maps a to index 0, and a migration that says to go from schema0 to schema1 when a is added. This schema is then attached to the instance that had a added;
Key b is added to the map. This creates schema2 that maps b to index 1, and a migration that says to go from schema1 to schema2 when b is added. This schema is then attached ot the instance that had b added.
When either a key is deleted, or the array becomes too large (must be determined based on performance tests), the backing storage for the object switches to a hash based store (current implementation). To make backing storage for instances even smaller, we could also state that we also automatically switch to classic storage when either an accessor is added or when either of the properties (writable, configurable, enumerable) is set to false.
This scheme has two primary advantages:
Objects require (far) less storage;
Certain optimizations become a lot simpler. The JIT could depend on this scheme and hard code schema ID's into the code, optimizing access to simple array access when the schema equals some known schema.
Objects currently only support a hash based backing storage. Schema based storage should be implemented too.
The idea of schema based storage is that storage is separated into two parts. The backing storage for the object itself becomes a simple array. Indexes into this array are determined by a schema. This schema is a hash that maps names to indexes.
Every time a new key is added to the object, a new schema is created. This new schema is a copy of the previous schema that maps the new name to the end of the array. These two schemas are then connected to each other using a migration step, so:
schema0
;a
is added to the map. This createsschema1
that mapsa
to index0
, and a migration that says to go fromschema0
toschema1
whena
is added. This schema is then attached to the instance that hada
added;b
is added to the map. This createsschema2
that mapsb
to index1
, and a migration that says to go fromschema1
toschema2
whenb
is added. This schema is then attached ot the instance that hadb
added.When either a key is deleted, or the array becomes too large (must be determined based on performance tests), the backing storage for the object switches to a hash based store (current implementation). To make backing storage for instances even smaller, we could also state that we also automatically switch to classic storage when either an accessor is added or when either of the properties (writable, configurable, enumerable) is set to
false
.This scheme has two primary advantages:
See e.g. http://jayconrod.com/posts/52/a-tour-of-v8-object-representation for more information on this.