Element Kind Exercise
This exercise will demonstrate creating arrays with various element kinds, and transitioning between kinds.
You can launch a v8 REPL under gdb
with exercise run v8 --gdb
.
Find Element Kind of an Array
- Create an array with some number of elements
- Call
%DebugPrint
on the array and look for "elements kind" under the array's Map
Create Different Types of Arrays
Try to create an array with each of the following element kinds:
PACKED_DOUBLE_ELEMENTS
PACKED_SMI_ELEMENTS
PACKED_ELEMENTS
HOLEY_DOUBLE_ELEMENTS
HOLEY_ELEMENTS
DICTIONARY_ELEMENTS
Reveal Answer
JavaScriptlet a = [1.1, 1.1, 1.1, 1.1]; // PACKED_DOUBLE_ELEMENTS
let b = [41, 41, 41, 41]; // PACKED_SMI_ELEMENTS
let c = [1.1, 41, {}, []]; // PACKED_ELEMENTS
let d = [1.1]; d[3]=1.1; // HOLEY_DOUBLE_ELEMENTS
let e = [1.1]; e[3]={}; // HOLEY_ELEMENTS
let f = [1.1]; f[10000]=1.1; // DICTIONARY_ELEMENTS
Examining Array Memory
For each of the array types you want to examine:
- Print the array's memory address using
%DebugPrint
(make sure to subtract 1 from the address before using it to remove the tag bit) - Break into gdb by hitting
ctrl-c
or running%SystemBreak()
- Dump the arrays memory using
x/100gx <address>
- Does the memory match how you expect each element kind to be stored?
Tracing Element Kind Transitions
Now experiment with transitioning an array through various element kinds.
- Create an array with a specific element kind (such as
PACKED_DOUBLE_ELEMENTS
) - Add an element to the array which would cause the element kind to change (such as adding a string or object to a
PACKED_DOUBLE_ELEMENTS
array) - Use
%DebugPrint
to observe the new element kind
Noted8 provides a flag
--trace-elements-transitions
intended to log a message every time the Map of an object or array has its element kind changed. This logging, however, doesn't always trigger for all transitions, so manually using%DebugPrint
is recommended. We mention this flag for reference.
For the following snippet, try to infer the resulting element kind for each statement. Execute each line and use %DebugPrint
to check your assumptions.
JavaScriptlet a = [1, 2, 3]
a[3] = 4.4
a[4] = true
delete a[1]
a[5000] = 7
Reveal Answer
JavaScriptlet a = [1, 2, 3] // PACKED_SMI_ELEMENTS
a[3] = 4.4 // PACKED_DOUBLE_ELEMENTS
a[4] = true // PACKED_ELEMENTS
delete a[1] // HOLEY_ELEMENTS
a[5000] = 7 // DICTIONARY_ELEMENTS