scripts: Use depth to limit recursive result collection
If we're not using these results, no reason to collect all of the children. Note that we still need to recurse for other measurements (limit, struct size, etc). This has a measurable, but small, impact on runtime: stack.py -z0 -Y: 0.202s stack.py -z1 -Y: 0.162s (~-19.8%) ctx.py -z0 -Y: 0.112s ctx.py -z1 -Y: 0.098s (~-12.5%)
This commit is contained in:
+9
-5
@@ -583,6 +583,7 @@ def collect_dwarf_info(obj_path, tags=None, *,
|
|||||||
def collect(obj_paths, *,
|
def collect(obj_paths, *,
|
||||||
sources=None,
|
sources=None,
|
||||||
everything=False,
|
everything=False,
|
||||||
|
depth=1,
|
||||||
**args):
|
**args):
|
||||||
results = []
|
results = []
|
||||||
for obj_path in obj_paths:
|
for obj_path in obj_paths:
|
||||||
@@ -678,10 +679,13 @@ def collect(obj_paths, *,
|
|||||||
return size
|
return size
|
||||||
|
|
||||||
# recursive+cached children finder
|
# recursive+cached children finder
|
||||||
def childrenof(entry, seen=set()):
|
def childrenof(entry, depth, seen=set()):
|
||||||
# found a cycle? stop here
|
# found a cycle? stop here
|
||||||
if entry.off in seen:
|
if entry.off in seen:
|
||||||
return [], {'cycle detected'}, True
|
return [], {'cycle detected'}, True
|
||||||
|
# stop here?
|
||||||
|
if depth < 1:
|
||||||
|
return [], set(), False
|
||||||
# cached?
|
# cached?
|
||||||
if not hasattr(childrenof, 'cache'):
|
if not hasattr(childrenof, 'cache'):
|
||||||
childrenof.cache = {}
|
childrenof.cache = {}
|
||||||
@@ -708,7 +712,7 @@ def collect(obj_paths, *,
|
|||||||
name_ = type.name
|
name_ = type.name
|
||||||
size_ = sizeof(type, seen | {entry.off})
|
size_ = sizeof(type, seen | {entry.off})
|
||||||
children_, notes_, dirty_ = childrenof(
|
children_, notes_, dirty_ = childrenof(
|
||||||
type, seen | {entry.off})
|
type, depth-1, seen | {entry.off})
|
||||||
children.append(CtxResult(file_, name_, size_,
|
children.append(CtxResult(file_, name_, size_,
|
||||||
children=children_,
|
children=children_,
|
||||||
notes=notes_))
|
notes=notes_))
|
||||||
@@ -729,7 +733,7 @@ def collect(obj_paths, *,
|
|||||||
name_ = child.name
|
name_ = child.name
|
||||||
size_ = sizeof(child, seen | {entry.off})
|
size_ = sizeof(child, seen | {entry.off})
|
||||||
children_, notes_, dirty_ = childrenof(
|
children_, notes_, dirty_ = childrenof(
|
||||||
child, seen | {entry.off})
|
child, depth-1, seen | {entry.off})
|
||||||
children.append(CtxResult(file_, name_, size_,
|
children.append(CtxResult(file_, name_, size_,
|
||||||
i=child.off,
|
i=child.off,
|
||||||
children=children_,
|
children=children_,
|
||||||
@@ -753,7 +757,7 @@ def collect(obj_paths, *,
|
|||||||
and 'DW_AT_type' in entry):
|
and 'DW_AT_type' in entry):
|
||||||
type = int(entry['DW_AT_type'].strip('<>'), 0)
|
type = int(entry['DW_AT_type'].strip('<>'), 0)
|
||||||
children, notes, dirty = childrenof(
|
children, notes, dirty = childrenof(
|
||||||
info[type], seen | {entry.off})
|
info[type], depth, seen | {entry.off})
|
||||||
# void?
|
# void?
|
||||||
elif ('DW_AT_type' not in entry
|
elif ('DW_AT_type' not in entry
|
||||||
and 'DW_AT_byte_size' not in entry):
|
and 'DW_AT_byte_size' not in entry):
|
||||||
@@ -815,7 +819,7 @@ def collect(obj_paths, *,
|
|||||||
size_ = sizeof(param)
|
size_ = sizeof(param)
|
||||||
|
|
||||||
# find children, recursing if necessary
|
# find children, recursing if necessary
|
||||||
children_, notes_, _ = childrenof(param)
|
children_, notes_, _ = childrenof(param, depth-2)
|
||||||
|
|
||||||
params.append(CtxResult(file_, name_, size_,
|
params.append(CtxResult(file_, name_, size_,
|
||||||
i=param.off,
|
i=param.off,
|
||||||
|
|||||||
+8
-3
@@ -718,6 +718,7 @@ def collect_callgraph(ci_path,
|
|||||||
def collect(obj_paths, ci_paths, *,
|
def collect(obj_paths, ci_paths, *,
|
||||||
sources=None,
|
sources=None,
|
||||||
everything=False,
|
everything=False,
|
||||||
|
depth=1,
|
||||||
**args):
|
**args):
|
||||||
# parse the callgraphs
|
# parse the callgraphs
|
||||||
cg = {}
|
cg = {}
|
||||||
@@ -764,10 +765,13 @@ def collect(obj_paths, ci_paths, *,
|
|||||||
return frame + limit
|
return frame + limit
|
||||||
|
|
||||||
# recursive+cached children finder
|
# recursive+cached children finder
|
||||||
def childrenof(node, seen=set()):
|
def childrenof(node, depth, seen=set()):
|
||||||
# found a cycle? stop here
|
# found a cycle? stop here
|
||||||
if node.name in seen:
|
if node.name in seen:
|
||||||
return [], {'cycle detected'}, True
|
return [], {'cycle detected'}, True
|
||||||
|
# stop here?
|
||||||
|
if depth < 1:
|
||||||
|
return [], set(), False
|
||||||
# cached?
|
# cached?
|
||||||
if not hasattr(childrenof, 'cache'):
|
if not hasattr(childrenof, 'cache'):
|
||||||
childrenof.cache = {}
|
childrenof.cache = {}
|
||||||
@@ -783,7 +787,8 @@ def collect(obj_paths, ci_paths, *,
|
|||||||
name_ = node_.name.split(':', 1)[-1]
|
name_ = node_.name.split(':', 1)[-1]
|
||||||
frame_ = frameof(node_)
|
frame_ = frameof(node_)
|
||||||
limit_ = limitof(node_, seen | {node.name})
|
limit_ = limitof(node_, seen | {node.name})
|
||||||
children_, notes_, dirty_ = childrenof(node_, seen | {node.name})
|
children_, notes_, dirty_ = childrenof(
|
||||||
|
node_, depth-1, seen | {node.name})
|
||||||
children.append(StackResult(file_, name_, frame_, limit_,
|
children.append(StackResult(file_, name_, frame_, limit_,
|
||||||
children=children_,
|
children=children_,
|
||||||
notes=notes_))
|
notes=notes_))
|
||||||
@@ -854,7 +859,7 @@ def collect(obj_paths, ci_paths, *,
|
|||||||
name = sym.name
|
name = sym.name
|
||||||
frame = frameof(node)
|
frame = frameof(node)
|
||||||
limit = limitof(node)
|
limit = limitof(node)
|
||||||
children, notes, _ = childrenof(node)
|
children, notes, _ = childrenof(node, depth-1)
|
||||||
results.append(StackResult(file, name, frame, limit,
|
results.append(StackResult(file, name, frame, limit,
|
||||||
children=children,
|
children=children,
|
||||||
notes=notes))
|
notes=notes))
|
||||||
|
|||||||
Reference in New Issue
Block a user