@@ -14,7 +14,7 @@ def maybe_unwrap_atomic(n):
14
14
return n .cast (underlying_type )
15
15
else :
16
16
return n
17
-
17
+
18
18
def maybe_unwrap_foa_element (e ):
19
19
if f"{ e .type .strip_typedefs ()} " .startswith ("boost::unordered::detail::foa::element_type<" ):
20
20
return e ["p" ]
@@ -84,7 +84,7 @@ def generator():
84
84
count += 1
85
85
node = self .cpo .to_address (node .dereference ()["next" ])
86
86
bucket_index += 1
87
-
87
+
88
88
return generator ()
89
89
90
90
class BoostUnorderedFcaIteratorPrinter :
@@ -119,7 +119,7 @@ def generator():
119
119
yield "" , member
120
120
yield "" , self .val [member ]
121
121
return generator ()
122
-
122
+
123
123
class BoostUnorderedFoaCumulativeStatsPrinter :
124
124
def __init__ (self , val ):
125
125
self .val = val
@@ -128,7 +128,7 @@ def __init__(self, val):
128
128
129
129
def display_hint (self ):
130
130
return "map"
131
-
131
+
132
132
def children (self ):
133
133
def generator ():
134
134
yield "" , "count"
@@ -161,6 +161,11 @@ def __init__(self, val):
161
161
self .name = self .name .replace ("boost::unordered::" , "boost::" )
162
162
self .is_map = self .name .endswith ("map" )
163
163
self .cpo = BoostUnorderedPointerCustomizationPoint (self .table ["arrays" ]["groups_" ])
164
+ self .groups = self .cpo .to_address (self .table ["arrays" ]["groups_" ])
165
+ self .elements = self .cpo .to_address (self .table ["arrays" ]["elements_" ])
166
+
167
+ self .N = 15 # `self.groups.dereference()["N"]` may be optimized out
168
+ self .sentinel_ = 1 # `self.groups.dereference()["sentinel_"]` may be optimized out
164
169
165
170
def to_string (self ):
166
171
size = BoostUnorderedHelpers .maybe_unwrap_atomic (self .table ["size_ctrl" ]["size" ])
@@ -193,29 +198,21 @@ def is_sentinel(self, group, pos):
193
198
m = group ["m" ]
194
199
at = lambda b : BoostUnorderedHelpers .maybe_unwrap_atomic (m [b ]["n" ])
195
200
196
- N = group ["N" ]
197
- sentinel_ = group ["sentinel_" ]
198
201
if self .is_regular_layout (group ):
199
- return pos == N - 1 and at (N - 1 ) == sentinel_
202
+ return pos == self . N - 1 and at (self . N - 1 ) == self . sentinel_
200
203
else :
201
- return pos == N - 1 and (at (0 ) & 0x4000400040004000 ) == 0x4000 and (at (1 ) & 0x4000400040004000 ) == 0
204
+ return pos == self . N - 1 and (at (0 ) & 0x4000400040004000 ) == 0x4000 and (at (1 ) & 0x4000400040004000 ) == 0
202
205
203
206
def children (self ):
204
207
def generator ():
205
- groups = self .cpo .to_address (self .table ["arrays" ]["groups_" ])
206
- elements = self .cpo .to_address (self .table ["arrays" ]["elements_" ])
207
-
208
- pc_ = groups .cast (gdb .lookup_type ("unsigned char" ).pointer ())
209
- p_ = elements
208
+ pc_ = self .groups .cast (gdb .lookup_type ("unsigned char" ).pointer ())
209
+ p_ = self .elements
210
210
first_time = True
211
- mask = 0
212
- n0 = 0
213
- n = 0
214
211
215
212
count = 0
216
213
while p_ != 0 :
217
214
# This if block mirrors the condition in the begin() call
218
- if (not first_time ) or (self .match_occupied (groups .dereference ()) & 1 ):
215
+ if (not first_time ) or (self .match_occupied (self . groups .dereference ()) & 1 ):
219
216
pointer = BoostUnorderedHelpers .maybe_unwrap_foa_element (p_ )
220
217
value = self .cpo .to_address (pointer ).dereference ()
221
218
if self .is_map :
@@ -229,17 +226,17 @@ def generator():
229
226
count += 1
230
227
first_time = False
231
228
232
- n0 = pc_ .cast (gdb .lookup_type ("uintptr_t" )) % groups .dereference ().type .sizeof
229
+ n0 = pc_ .cast (gdb .lookup_type ("uintptr_t" )) % self . groups .dereference ().type .sizeof
233
230
pc_ = self .cpo .next (pc_ , - n0 )
234
231
235
- mask = (self .match_occupied (pc_ .cast (groups .type ).dereference ()) >> (n0 + 1 )) << (n0 + 1 )
232
+ mask = (self .match_occupied (pc_ .cast (self . groups .type ).dereference ()) >> (n0 + 1 )) << (n0 + 1 )
236
233
while mask == 0 :
237
- pc_ = self .cpo .next (pc_ , groups .dereference ().type .sizeof )
238
- p_ = self .cpo .next (p_ , groups . dereference ()[ "N" ] )
239
- mask = self .match_occupied (pc_ .cast (groups .type ).dereference ())
240
-
234
+ pc_ = self .cpo .next (pc_ , self . groups .dereference ().type .sizeof )
235
+ p_ = self .cpo .next (p_ , self . N )
236
+ mask = self .match_occupied (pc_ .cast (self . groups .type ).dereference ())
237
+
241
238
n = BoostUnorderedHelpers .countr_zero (mask )
242
- if self .is_sentinel (pc_ .cast (groups .type ).dereference (), n ):
239
+ if self .is_sentinel (pc_ .cast (self . groups .type ).dereference (), n ):
243
240
p_ = 0
244
241
else :
245
242
pc_ = self .cpo .next (pc_ , n )
@@ -285,7 +282,7 @@ def boost_unordered_build_pretty_printer():
285
282
add_template_printer ("boost::unordered::concurrent_flat_set" , BoostUnorderedFoaPrinter )
286
283
add_template_printer ("boost::unordered::concurrent_node_map" , BoostUnorderedFoaPrinter )
287
284
add_template_printer ("boost::unordered::concurrent_node_set" , BoostUnorderedFoaPrinter )
288
-
285
+
289
286
add_template_printer ("boost::unordered::detail::foa::table_iterator" , BoostUnorderedFoaIteratorPrinter )
290
287
291
288
add_concrete_printer ("boost::unordered::detail::foa::table_core_cumulative_stats" , BoostUnorderedFoaTableCoreCumulativeStatsPrinter )
@@ -302,7 +299,7 @@ def boost_unordered_build_pretty_printer():
302
299
class BoostUnorderedFoaGetStatsMethod (gdb .xmethod .XMethod ):
303
300
def __init__ (self ):
304
301
gdb .xmethod .XMethod .__init__ (self , "get_stats" )
305
-
302
+
306
303
def get_worker (self , method_name ):
307
304
if method_name == "get_stats" :
308
305
return BoostUnorderedFoaGetStatsWorker ()
@@ -313,19 +310,19 @@ def get_arg_types(self):
313
310
314
311
def get_result_type (self , obj ):
315
312
return gdb .lookup_type ("boost::unordered::detail::foa::table_core_cumulative_stats" )
316
-
313
+
317
314
def __call__ (self , obj ):
318
315
try :
319
316
return obj ["table_" ]["cstats" ]
320
317
except gdb .error :
321
318
print ("Error: Binary was compiled without stats. Recompile with `BOOST_UNORDERED_ENABLE_STATS` defined." )
322
319
return
323
-
320
+
324
321
class BoostUnorderedFoaMatcher (gdb .xmethod .XMethodMatcher ):
325
322
def __init__ (self ):
326
323
gdb .xmethod .XMethodMatcher .__init__ (self , 'BoostUnorderedFoaMatcher' )
327
324
self .methods = [BoostUnorderedFoaGetStatsMethod ()]
328
-
325
+
329
326
def match (self , class_type , method_name ):
330
327
template_name = f"{ class_type .strip_typedefs ()} " .split ("<" )[0 ]
331
328
regex = "^boost::unordered::(unordered|concurrent)_(flat|node)_(map|set)$"
@@ -381,12 +378,12 @@ class MyFancyPtrPrinter:
381
378
def boost_to_address(fancy_ptr):
382
379
...
383
380
return ...
384
-
381
+
385
382
# Equivalent to `operator+()`
386
383
def boost_next(raw_ptr, offset):
387
384
...
388
385
return ...
389
-
386
+
390
387
...
391
388
```
392
389
"""
0 commit comments