From 0c1913336af42b6d789fa7738690e64b7784d9df Mon Sep 17 00:00:00 2001 From: Geoffrey Blake Date: Fri, 9 May 2014 18:58:47 -0400 Subject: config: Avoid generating a reference to myself for Parent.any The unproxy code for Parent.any can generate a circular reference in certain situations with classes hierarchies like those in ClockDomain.py. This patch solves this by marking ouself as visited to make sure the search does not resolve to a self-reference. --- src/python/m5/SimObject.py | 6 +++++- src/python/m5/proxy.py | 22 ++++++++++++++++++---- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 30c968380..3784c716e 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -861,7 +861,11 @@ class SimObject(object): found_obj = None for child in self._children.itervalues(): - if isinstance(child, ptype): + visited = False + if hasattr(child, '_visited'): + visited = getattr(child, '_visited') + + if isinstance(child, ptype) and not visited: if found_obj != None and child != found_obj: raise AttributeError, \ 'parent.any matched more than one: %s %s' % \ diff --git a/src/python/m5/proxy.py b/src/python/m5/proxy.py index 4582b8f09..a99d3715c 100644 --- a/src/python/m5/proxy.py +++ b/src/python/m5/proxy.py @@ -82,12 +82,19 @@ class BaseProxy(object): result, done = self.find(obj) if self._search_up: + # Search up the tree but mark ourself + # as visited to avoid a self-reference + self._visited = True + obj._visited = True while not done: obj = obj._parent if not obj: break result, done = self.find(obj) + self._visited = False + base._visited = False + if not done: raise AttributeError, \ "Can't resolve proxy '%s' of type '%s' from '%s'" % \ @@ -151,10 +158,17 @@ class AttrProxy(BaseProxy): def find(self, obj): try: val = getattr(obj, self._attr) - # for any additional unproxying to be done, pass the - # current, rather than the original object so that proxy - # has the right context - obj = val + visited = False + if hasattr(val, '_visited'): + visited = getattr(val, '_visited') + + if not visited: + # for any additional unproxying to be done, pass the + # current, rather than the original object so that proxy + # has the right context + obj = val + else: + return None, False except: return None, False while isproxy(val): -- cgit v1.2.3