3 _map_capping_size
= 255
6 class libcxx_hash_table_SynthProvider
:
7 def __init__(self
, valobj
, dict):
9 self
.num_elements
= None
10 self
.next_element
= None
11 self
.bucket_count
= None
14 logger
= lldb
.formatters
.Logger
.Logger()
15 self
.num_elements
= None
16 self
.next_element
= None
17 self
.bucket_count
= None
19 # unordered_map is made up of a hash_map, which has 4 pieces in it:
23 # first - pointer to first loaded element
25 # first - number of elements
26 # second - hash function
28 # first - max_load_factor
29 # second - equality operator function
31 # For display, we actually don't need to go inside the buckets, since 'p1' has a way to iterate over all
32 # the elements directly.
34 # We will calculate other values about the map because they will be useful for the summary.
36 table
= self
.valobj
.GetChildMemberWithName("__table_")
38 bl_ptr
= table
.GetChildMemberWithName(
40 ).GetChildMemberWithName("__ptr_")
41 self
.bucket_array_ptr
= bl_ptr
.GetChildMemberWithName(
43 ).GetValueAsUnsigned(0)
45 bl_ptr
.GetChildMemberWithName("__second_")
46 .GetChildMemberWithName("__data_")
47 .GetChildMemberWithName("__first_")
48 .GetValueAsUnsigned(0)
50 logger
>> "Bucket count = %r" % self
.bucket_count
53 table
.GetChildMemberWithName("__p1_")
54 .GetChildMemberWithName("__first_")
55 .GetChildMemberWithName("__next_")
59 table
.GetChildMemberWithName("__p2_")
60 .GetChildMemberWithName("__first_")
61 .GetValueAsUnsigned(0)
63 self
.max_load_factor
= (
64 table
.GetChildMemberWithName("__p3_")
65 .GetChildMemberWithName("__first_")
66 .GetValueAsUnsigned(0)
68 logger
>> "Num elements = %r" % self
.num_elements
70 # save the pointers as we get them
71 # -- don't access this first element if num_element==0!
72 self
.elements_cache
= []
74 self
.next_element
= self
.begin_ptr
76 self
.next_element
= None
77 except Exception as e
:
78 logger
>> "Caught exception: %r" % e
81 def num_children(self
):
82 global _map_capping_size
83 num_elements
= self
.num_elements
84 if num_elements
is not None:
85 if num_elements
> _map_capping_size
:
86 num_elements
= _map_capping_size
89 def has_children(self
):
92 def get_child_index(self
, name
):
93 logger
= lldb
.formatters
.Logger
.Logger()
95 return int(name
.lstrip("[").rstrip("]"))
99 def get_child_at_index(self
, index
):
100 logger
= lldb
.formatters
.Logger
.Logger()
101 logger
>> "Retrieving child " + str(index
)
104 if index
>= self
.num_children():
108 logger
>> " : cache size starts with %d elements" % len(self
.elements_cache
)
109 while index
>= len(self
.elements_cache
):
110 # if we hit the end before we get the index, give up:
111 if not self
.next_element
:
112 logger
>> " : hit end of list"
115 node
= self
.next_element
.Dereference()
117 value
= node
.GetChildMemberWithName("__value_")
118 hash_value
= node
.GetChildMemberWithName("__hash_").GetValueAsUnsigned()
119 self
.elements_cache
.append((value
, hash_value
))
121 self
.next_element
= node
.GetChildMemberWithName("__next_")
122 if not self
.next_element
.GetValueAsUnsigned(0):
123 self
.next_element
= None
125 # hit the index! so we have the value
126 logger
>> " : cache size ends with %d elements" % len(self
.elements_cache
)
127 value
, hash_value
= self
.elements_cache
[index
]
128 return self
.valobj
.CreateValueFromData(
129 "[%d] <hash %d>" % (index
, hash_value
), value
.GetData(), value
.GetType()
133 def __lldb_init_module(debugger
, dict):
134 debugger
.HandleCommand(
135 'type synthetic add -l unordered_multi.libcxx_hash_table_SynthProvider -x "^(std::__1::)unordered_(multi)?(map|set)<.+> >$" -w libcxx'