From 3efc18e33dac8760e07642a74c26519c3467c306 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Sat, 26 Nov 2011 16:37:02 +0200 Subject: [PATCH] add caching to LocationExpressionDumper in _location_list_extra. this makes some benchmarks considerably faster --- elftools/dwarf/descriptions.py | 13 ++++++++++++- elftools/dwarf/location_expr.py | 7 +++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/elftools/dwarf/descriptions.py b/elftools/dwarf/descriptions.py index 037aa7e..ddb8f6b 100644 --- a/elftools/dwarf/descriptions.py +++ b/elftools/dwarf/descriptions.py @@ -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() + ')' diff --git a/elftools/dwarf/location_expr.py b/elftools/dwarf/location_expr.py index 09445d7..1d92da3 100644 --- a/elftools/dwarf/location_expr.py +++ b/elftools/dwarf/location_expr.py @@ -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', -- 2.30.2