+# Version 20.1.0.0
+
+* m5.stats.dump() root argument renamed to roots to reflect the fact that it now takes a list of SimObjects
+
# Version 20.0.0.2
**[HOTFIX]** A patch was applied to fix the RubyPrefetcher with MESI_Three_Level. Prior to this fix a segfault occurred.
parser.add_option("--arm-iset", default="arm", type="choice",
choices=["arm", "thumb", "aarch64"],
help="ARM instruction set.")
+ parser.add_option("--stats-root", action="append", default=[], help=
+ "If given, dump only stats of objects under the given SimObject. "
+ "SimObjects are identified with Python notation as in: "
+ "system.cpu[0].dtb. All elements of an array can be selected at "
+ "once with: system.cpu[:].dtb. If given multiple times, dump stats "
+ "that are present under any of the roots. If not given, dump all "
+ "stats. "
+ )
def addSEOptions(parser):
if options.repeat_switch and options.take_checkpoints:
fatal("Can't specify both --repeat-switch and --take-checkpoints")
+ # Setup global stat filtering.
+ stat_root_simobjs = []
+ for stat_root_str in options.stats_root:
+ stat_root_simobjs.extend(root.get_simobj(stat_root_str))
+ m5.stats.global_dump_roots = stat_root_simobjs
+
np = options.num_cpus
switch_cpus = None
-# Copyright (c) 2017-2019 ARM Limited
+# Copyright (c) 2017-2020 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
out.extend(sim_object[i] for i in _range)
return SimObjectCliWrapper(out)
+ def __iter__(self):
+ return iter(self._sim_objects)
+
# The SimObject class is the root of the special hierarchy. Most of
# the code in this class deals with the configuration hierarchy itself
# (parent/child node relationships).
for param in params:
exec(param, d)
+ def get_simobj(self, simobj_path):
+ """
+ Get all sim objects that match a given string.
+
+ The format is the same as that supported by SimObjectCliWrapper.
+
+ :param simobj_path: Current state to be in.
+ :type simobj_path: str
+ """
+ d = self._apply_config_get_dict()
+ return eval(simobj_path, d)
+
# Function to provide to C++ so it can look up instances based on paths
def resolveSimObject(name):
obj = instanceDict[name]
# New stats
_visit_stats(lambda g, s: s.prepare())
-def _dump_to_visitor(visitor, root=None):
- # Legacy stats
- if root is None:
- for stat in stats_list:
- stat.visit(visitor)
-
+def _dump_to_visitor(visitor, roots=None):
# New stats
def dump_group(group):
for stat in group.getStats():
stat.visit(visitor)
-
for n, g in group.getStatGroups().items():
visitor.beginGroup(n)
dump_group(g)
visitor.endGroup()
- if root is not None:
- for p in root.path_list():
- visitor.beginGroup(p)
- dump_group(root if root is not None else Root.getInstance())
- if root is not None:
- for p in reversed(root.path_list()):
- visitor.endGroup()
+ if roots:
+ # New stats from selected subroots.
+ for root in roots:
+ for p in root.path_list():
+ visitor.beginGroup(p)
+ dump_group(root)
+ for p in reversed(root.path_list()):
+ visitor.endGroup()
+ else:
+ # Legacy stats
+ for stat in stats_list:
+ stat.visit(visitor)
+
+ # New stats starting from root.
+ dump_group(Root.getInstance())
lastDump = 0
+# List[SimObject].
+global_dump_roots = []
-def dump(root=None):
+def dump(roots=None):
'''Dump all statistics data to the registered outputs'''
+ all_roots = []
+ if roots is not None:
+ all_roots.extend(roots)
+ global global_dump_roots
+ all_roots.extend(global_dump_roots)
+
now = m5.curTick()
global lastDump
assert lastDump <= now
# Don't allow multiple global stat dumps in the same tick. It's
# still possible to dump a multiple sub-trees.
- if not new_dump and root is None:
+ if not new_dump and not all_roots:
return
# Only prepare stats the first time we dump them in the same tick.
for output in outputList:
if output.valid():
output.begin()
- _dump_to_visitor(output, root=root)
+ _dump_to_visitor(output, roots=all_roots)
output.end()
def reset():