[IMP] base: flatten view post-processing recursion

The post-processing of a view was implemented as a recursion, the
processing of every XML node recursively processing its children nodes.
Recursion inside flamegraphs scatters sub-calls at many call depths,
which makes their analysis less obvious.  Transforming the recursion
into a loop with a stack makes the code more profiler-friendly.

Task: 2463632
This commit is contained in:
Julien Castiaux
2021-06-11 17:09:05 +00:00
parent c0ab436723
commit 50197d7337
+33 -29
View File
@@ -1010,40 +1010,44 @@ actual arch.
""" Process the given arch node, which may be the complete arch or some
subnode, and fill in the name manager with field information.
"""
# compute default
tag = node.tag
parent = node.getparent()
node_info = dict(
modifiers={},
attr_model=name_manager.Model,
editable=editable,
)
current_node_path = current_node_path + [tag]
stack = [(node, current_node_path, editable)]
while stack:
node, current_node_path, editable = stack.pop()
postprocessor = getattr(self, '_postprocess_tag_%s' % tag, False)
if postprocessor:
postprocessor(node, name_manager, node_info)
if node.getparent() is not parent:
# the node has been removed, stop processing here
return
# compute default
tag = node.tag
parent = node.getparent()
node_info = dict(
modifiers={},
attr_model=name_manager.Model,
editable=editable,
)
current_node_path = current_node_path + [tag]
elif tag in {item[0] for item in type(self.env['ir.ui.view']).type.selection}:
node_info['editable'] = False
postprocessor = getattr(self, '_postprocess_tag_%s' % tag, False)
if postprocessor:
postprocessor(node, name_manager, node_info)
if node.getparent() is not parent:
# the node has been removed, stop processing here
continue
if name_manager.validate:
# structure validation
validator = getattr(self, '_validate_tag_%s' % tag, False)
if validator:
validator(node, name_manager, node_info)
self._validate_attrs(node, name_manager, node_info)
elif tag in {item[0] for item in type(self.env['ir.ui.view']).type.selection}:
node_info['editable'] = False
self._apply_groups(node, name_manager, node_info)
transfer_node_to_modifiers(node, node_info['modifiers'], self._context, current_node_path)
transfer_modifiers_to_node(node_info['modifiers'], node)
if name_manager.validate:
# structure validation
validator = getattr(self, '_validate_tag_%s' % tag, False)
if validator:
validator(node, name_manager, node_info)
self._validate_attrs(node, name_manager, node_info)
# if present, iterate on node_info['children'] instead of node
for child in node_info.get('children', node):
self.postprocess(child, current_node_path, node_info['editable'], name_manager)
self._apply_groups(node, name_manager, node_info)
transfer_node_to_modifiers(node, node_info['modifiers'], self._context, current_node_path)
transfer_modifiers_to_node(node_info['modifiers'], node)
# if present, iterate on node_info['children'] instead of node
for child in reversed(node_info.get('children', node)):
stack.append((child, current_node_path, node_info['editable']))
#------------------------------------------------------
# Specific node postprocessors