Author: Armin Rigo <ar...@tunes.org>
Branch: stm-gc
Changeset: r54716:9ac765b1a237
Date: 2012-04-24 11:05 +0200
http://bitbucket.org/pypy/pypy/changeset/9ac765b1a237/

Log:    Add a passing test.

diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py 
b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -338,6 +338,97 @@
         assert obj == t_adr                       # doesn't make a copy
         self.checkflags(obj, False, False)        # but it becomes local
 
+    def test_nontransactional_mode(self):
+        import random
+        from pypy.rpython.memory.gc.test import test_stmtls
+        self.gc.root_walker = test_stmtls.FakeRootWalker()
+        #
+        def reachable(source_objects):
+            pending = list(source_objects)
+            found = set(obj._obj for obj in pending)
+            for x in pending:
+                for name in ('sr2', 'sr3'):
+                    obj = getattr(x, name)
+                    if obj and obj._obj not in found:
+                        found.add(obj._obj)
+                        pending.append(obj)
+            return found
+        #
+        def shape_of_reachable(source_object):
+            shape = []
+            pending = [source_object]
+            found = {source_object._obj: 0}
+            for x in pending:
+                for name in ('sr2', 'sr3'):
+                    obj = getattr(x, name)
+                    if not obj:
+                        shape.append(None)
+                    else:
+                        if obj._obj not in found:
+                            found[obj._obj] = len(found)
+                            pending.append(obj)
+                        shape.append(found[obj._obj])
+            return shape
+        #
+        prebuilt = [self.malloc(SR, globl=True)[0] for i in range(15)]
+        globals = set(obj._obj for obj in prebuilt)
+        root_objects = prebuilt[:]
+        all_objects = root_objects[:]
+        NO_OBJECT = lltype.nullptr(SR)
+        #
+        for iteration in range(10):
+            # add 6 freshly malloced objects from the nursery
+            new_objects = [self.malloc(SR, globl=False)[0] for i in range(6)]
+            all_objects = all_objects + new_objects
+            set_all_objects = set(obj._obj for obj in all_objects)
+            #
+            # pick 4 random objects to be stack roots
+            fromstack = random.sample(all_objects, 4)
+            root_objects = prebuilt + fromstack
+            #
+            # randomly add or remove connections between objects, until they
+            # are all reachable from root_objects
+            while True:
+                missing_objects = set_all_objects - reachable(root_objects)
+                if not missing_objects:
+                    break
+                srcobj = random.choice(all_objects)
+                # give a higher chance to 'missing_objects', but also
+                # allows other objects
+                missing_objects = [obj._as_ptr() for obj in missing_objects]
+                missing_objects.append(NO_OBJECT)
+                missing_objects *= 2
+                missing_objects.extend(all_objects)
+                dstobj = random.choice(missing_objects)
+                name = random.choice(('sr2', 'sr3'))
+                src_adr = llmemory.cast_ptr_to_adr(srcobj)
+                adr2 = self.gc.stm_writebarrier(src_adr)
+                assert adr2 == src_adr
+                setattr(srcobj, name, dstobj)
+                if srcobj._obj in globals:
+                    globals.remove(srcobj._obj)
+            #
+            # Record the shape of the graph of reachable objects
+            shapes = [shape_of_reachable(obj) for obj in root_objects]
+            #
+            # Do a collection
+            self.gc.root_walker.current_stack = fromstack[:]
+            self.gc.collect(0)
+            #
+            # Reload 'fromstack', which may have moved, and compare the shape
+            # of the graph of reachable objects now
+            fromstack[:] = self.gc.root_walker.current_stack
+            root_objects = prebuilt + fromstack
+            shapes2 = [shape_of_reachable(obj) for obj in root_objects]
+            assert shapes == shapes2
+            #
+            # Reset the list of all objects for the next iteration
+            all_objects = [obj._as_ptr() for obj in reachable(root_objects)]
+            #
+            # Check the GLOBAL flag, and check that the objects really survived
+            for obj in all_objects:
+                self.checkflags(obj, obj._obj in globals, False)
+
     def test_relocalize_objects_after_transactional_mode(self):
         from pypy.rpython.memory.gc.test import test_stmtls
         self.gc.root_walker = test_stmtls.FakeRootWalker()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to