config: Avoid generating a reference to myself for Parent.any
authorGeoffrey Blake <Geoffrey.Blake@arm.com>
Fri, 9 May 2014 22:58:47 +0000 (18:58 -0400)
committerGeoffrey Blake <Geoffrey.Blake@arm.com>
Fri, 9 May 2014 22:58:47 +0000 (18:58 -0400)
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
src/python/m5/proxy.py

index 30c96838079d9ce4fe5a392656bdbdc8e84d4744..3784c716e141938f6bfb9f93b87825cb9408dfa0 100644 (file)
@@ -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' % \
index 4582b8f091c6e48a523edf34e48a8136c374604a..a99d3715c72ca53543c51eca797b73d84d597b86 100644 (file)
@@ -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):