I’m learning more about v8
internals as a hobby project. For this example, I’m trying to debug and understand how Javascript Map.prototype.set
actually works under-the-hood.
I’m using v8
tag 9.9.99
.
I first create a new Map
object in:
V8 version 9.9.99
d8> x = new Map()
[object Map]
d8> x.set(10,-10)
[object Map]
d8> %DebugPrint(x)
DebugPrint: 0x346c0804ad25: [JSMap]
- map: 0x346c08202771 <Map(HOLEY_ELEMENTS)> [FastProperties]
- prototype: 0x346c081c592d <Object map = 0x346c08202799>
- elements: 0x346c08002249 <FixedArray[0]> [HOLEY_ELEMENTS]
- table: 0x346c0804ad35 <OrderedHashMap[17]>
- properties: 0x346c08002249 <FixedArray[0]>
- All own properties (excluding elements): {}
When I break out of d8
into gdb
, I look into the table
attribute
gef➤ job 0x346c0804ad35
0x346c0804ad35: [OrderedHashMap]
- FixedArray length: 17
- elements: 1
- deleted: 0
- buckets: 2
- capacity: 4
- buckets: {
0: -1
1: 0
}
- elements: {
0: 10 -> -10
}
Poking around the v8
source, I find what I think to be the code related to OrderedHashTable
and OrderedHashMap
in src/objects/ordered-hash-table.cc
. Specifically, line 368:
MaybeHandle<OrderedHashMap> OrderedHashMap::Add(Isolate* isolate,
Handle<OrderedHashMap> table,
Handle<Object> key,
Handle<Object> value) {
...
After reading the code, my assumption is that OrderedHashMap::Add()
will get triggered when you do Map.Prototype.Set
(i.e., adding a new element). So I set a breakpoint here in and continue
gef➤ b v8::internal::OrderedHashMap::Add(v8::internal::Isolate*,
v8::internal::Handle<v8::internal::OrderedHashMap>,
v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>)
Breakpoint 1 at 0x557eb3b491e4
gef➤ c
Continuing.
I then attempt to set a new element, but the breakpoint does not trigger
d8> x.set(11,-11)
[object Map]
Breaking out into gdb
again, it appears the element has been added
gef➤ job 0x346c0804ad35
0x346c0804ad35: [OrderedHashMap]
- FixedArray length: 17
- elements: 2
- deleted: 0
- buckets: 2
- capacity: 4
- buckets: {
0: 1
1: 0
}
- elements: {
0: 10 -> -10
1: 11 -> -11
}
Do I have the breakpoint set up in the wrong spot? And if so, would anyone have any recommendations for efficiently finding the JS equivalents in v8
?