add caching to LocationExpressionDumper in _location_list_extra. this makes some...
authorEli Bendersky <eliben@gmail.com>
Sat, 26 Nov 2011 14:37:02 +0000 (16:37 +0200)
committerEli Bendersky <eliben@gmail.com>
Sat, 26 Nov 2011 14:37:02 +0000 (16:37 +0200)
elftools/dwarf/descriptions.py
elftools/dwarf/location_expr.py

index 037aa7ed985d85ed8ce12b31c686a6a890d94618..ddb8f6bd1bc765c1f5c3b01ebb34679a221d8a33 100644 (file)
@@ -214,6 +214,8 @@ def _make_extra_string(s=''):
     return extra
 
 
+_LOCATION_EXPR_DUMPER_CACHE = {}
+
 def _location_list_extra(attr, die, section_offset):
     # According to section 2.6 of the DWARF spec v3, class loclistptr means
     # a location list, and class block means a location expression.
@@ -221,7 +223,16 @@ def _location_list_extra(attr, die, section_offset):
     if attr.form in ('DW_FORM_data4', 'DW_FORM_data8'):
         return '(location list)'
     else:
-        location_expr_dumper = LocationExpressionDumper(die.cu.structs)
+        # Since this function can be called a lot, initializing a fresh new
+        # LocationExpressionDumper per call is expensive. So a rudimentary
+        # caching scheme is in place to create only one such dumper per
+        # processed CU.
+        cache_key = id(die.cu.structs)
+        if cache_key not in _LOCATION_EXPR_DUMPER_CACHE:
+            _LOCATION_EXPR_DUMPER_CACHE[cache_key] = \
+                LocationExpressionDumper(die.cu.structs)
+        location_expr_dumper = _LOCATION_EXPR_DUMPER_CACHE[cache_key]
+        location_expr_dumper.clear()
         location_expr_dumper.process_expr(attr.value)
         return '(' + location_expr_dumper.get_str() + ')'
 
index 09445d7582986957ddb81e64a5c340db757f58b7..1d92da3dd83241e475571e50b666b4e5bf595285 100644 (file)
@@ -254,11 +254,14 @@ class LocationExpressionDumper(GenericLocationExprVisitor):
         super(LocationExpressionDumper, self).__init__(structs)
         self._init_lookups()
         self._str_parts = []
-    
+
+    def clear(self):
+        self._str_parts = []
+
     def get_str(self):
         return '; '.join(self._str_parts)
 
-    def _init_lookups(self):        
+    def _init_lookups(self):
         self._ops_with_decimal_arg = set([
             'DW_OP_const1u', 'DW_OP_const1s', 'DW_OP_const2u', 'DW_OP_const2s',
             'DW_OP_const4u', 'DW_OP_const4s', 'DW_OP_constu', 'DW_OP_consts',