[pypy-svn] r76933 - in pypy/branch/gc-module/pypy/module/gc: . test

arigo at codespeak.net arigo at codespeak.net
Wed Sep 8 10:30:38 CEST 2010


Author: arigo
Date: Wed Sep  8 10:30:33 2010
New Revision: 76933

Modified:
   pypy/branch/gc-module/pypy/module/gc/__init__.py
   pypy/branch/gc-module/pypy/module/gc/referents.py
   pypy/branch/gc-module/pypy/module/gc/test/test_referents.py
Log:
gc.get_referrers().


Modified: pypy/branch/gc-module/pypy/module/gc/__init__.py
==============================================================================
--- pypy/branch/gc-module/pypy/module/gc/__init__.py	(original)
+++ pypy/branch/gc-module/pypy/module/gc/__init__.py	Wed Sep  8 10:30:33 2010
@@ -24,6 +24,7 @@
                 'get_rpy_type_index': 'referents.get_rpy_type_index',
                 'get_objects': 'referents.get_objects',
                 'get_referents': 'referents.get_referents',
+                'get_referrers': 'referents.get_referrers',
                 'GcRef': 'referents.W_GcRef',
                 })
         MixedModule.__init__(self, space, w_name)

Modified: pypy/branch/gc-module/pypy/module/gc/referents.py
==============================================================================
--- pypy/branch/gc-module/pypy/module/gc/referents.py	(original)
+++ pypy/branch/gc-module/pypy/module/gc/referents.py	Wed Sep  8 10:30:33 2010
@@ -79,19 +79,23 @@
             else:
                 pending.append(gcref)
 
-def get_objects(space):
-    """Return a list of all app-level objects."""
-    roots = rgc.get_rpy_roots()
-    # start from the roots, which is a list of gcrefs that may or may not
-    # be W_Roots
-    pending_w = []   # <- list of W_Roots
-    for gcref in roots:
+def _get_objects_from_rpy(list_of_gcrefs):
+    # given a list of gcrefs that may or may not be W_Roots, build a list
+    # of W_Roots obtained by following references from there.
+    result_w = []   # <- list of W_Roots
+    for gcref in list_of_gcrefs:
         if gcref:
             w_obj = try_cast_gcref_to_w_root(gcref)
             if w_obj is not None:
-                pending_w.append(w_obj)
+                result_w.append(w_obj)
             else:
-                _list_w_obj_referents(gcref, pending_w)
+                _list_w_obj_referents(gcref, result_w)
+    return result_w
+
+def get_objects(space):
+    """Return a list of all app-level objects."""
+    roots = rgc.get_rpy_roots()
+    pending_w = _get_objects_from_rpy(roots)
     # continue by following every W_Root.  Note that this will force a hash
     # on every W_Root, which is kind of bad, but not on every RPython object,
     # which is really good.
@@ -116,3 +120,30 @@
         _list_w_obj_referents(gcref, result)
     return space.newlist(result)
 get_referents.unwrap_spec = [ObjSpace, 'args_w']
+
+def get_referrers(space, args_w):
+    """Return the list of objects that directly refer to any of objs."""
+    roots = rgc.get_rpy_roots()
+    pending_w = _get_objects_from_rpy(roots)
+    arguments_w = {}
+    for w_obj in args_w:
+        arguments_w[w_obj] = None
+    # continue by following every W_Root.  Same remark about hashes as
+    # in get_objects().
+    result_w = {}
+    seen_w = {}
+    while len(pending_w) > 0:
+        previous_w = pending_w
+        pending_w = []
+        for w_obj in previous_w:
+            if w_obj not in seen_w:
+                seen_w[w_obj] = None
+                gcref = rgc.cast_instance_to_gcref(w_obj)
+                referents_w = []
+                _list_w_obj_referents(gcref, referents_w)
+                for w_subobj in referents_w:
+                    if w_subobj in arguments_w:
+                        result_w[w_obj] = None
+                pending_w += referents_w
+    return space.newlist(result_w.keys())
+get_referrers.unwrap_spec = [ObjSpace, 'args_w']

Modified: pypy/branch/gc-module/pypy/module/gc/test/test_referents.py
==============================================================================
--- pypy/branch/gc-module/pypy/module/gc/test/test_referents.py	(original)
+++ pypy/branch/gc-module/pypy/module/gc/test/test_referents.py	Wed Sep  8 10:30:33 2010
@@ -93,3 +93,14 @@
         x = [y, z]
         lst = gc.get_referents(x)
         assert y in lst and z in lst
+
+    def test_get_referrers(self):
+        import gc
+        l27 = self.ALL_ROOTS[1]
+        i2, i7 = l27
+        lst = gc.get_referrers(i7)
+        for x in lst:
+            if x is l27:
+                break   # found
+        else:
+            assert 0, "the list [2, 7] is not found as gc.get_referrers(7)"



More information about the Pypy-commit mailing list