[pypy-commit] pypy stm-gc: Test and fix.

arigo noreply at buildbot.pypy.org
Tue Apr 17 11:20:43 CEST 2012


Author: Armin Rigo <arigo at tunes.org>
Branch: stm-gc
Changeset: r54453:140fbb1aac69
Date: 2012-04-17 10:49 +0200
http://bitbucket.org/pypy/pypy/changeset/140fbb1aac69/

Log:	Test and fix.

diff --git a/pypy/rpython/memory/gc/stmtls.py b/pypy/rpython/memory/gc/stmtls.py
--- a/pypy/rpython/memory/gc/stmtls.py
+++ b/pypy/rpython/memory/gc/stmtls.py
@@ -286,7 +286,7 @@
 
     def collect_roots_from_stack(self):
         self.gc.root_walker.walk_current_stack_roots(
-            StmGCTLS._trace_drag_out_if_not_global1, self)
+            StmGCTLS._trace_drag_out1, self)
 
     def trace_and_drag_out_of_nursery(self, obj):
         # This is called to fix the references inside 'obj', to ensure that
@@ -296,16 +296,8 @@
         # objects.
         self.gc.trace(obj, self._trace_drag_out, None)
 
-    def _trace_drag_out_if_not_global1(self, root):
-        self._trace_drag_out_if_not_global(root, None)
-
-    def _trace_drag_out_if_not_global(self, root, ignored):
-        # like _trace_drag_out(), but ignores references to GLOBAL objects.
-        # used only for the LOCAL copy of a GLOBAL object, which may still
-        # have further GLOBAL pointers.
-        obj = root.address[0]
-        if self.gc.header(obj).tid & GCFLAG_GLOBAL == 0:
-            self._trace_drag_out(root, ignored)
+    def _trace_drag_out1(self, root):
+        self._trace_drag_out(root, None)
 
     def _trace_drag_out(self, root, ignored):
         """Trace callback: 'root' is the address of some pointer.  If that
@@ -315,11 +307,12 @@
         """
         obj = root.address[0]
         hdr = self.gc.header(obj)
-        ll_assert(hdr.tid & GCFLAG_GLOBAL == 0, "unexpected GLOBAL obj")
         #
         # If 'obj' is not in the nursery, we set GCFLAG_VISITED
         if not self.is_in_nursery(obj):
-            if hdr.tid & GCFLAG_VISITED == 0:
+            # we ignore both GLOBAL objects and objects which have already
+            # been VISITED
+            if hdr.tid & (GCFLAG_GLOBAL|GCFLAG_VISITED) == 0:
                 ll_assert(hdr.tid & GCFLAG_WAS_COPIED == 0,
                           "local GCFLAG_WAS_COPIED without GCFLAG_VISITED")
                 hdr.tid |= GCFLAG_VISITED
@@ -423,7 +416,7 @@
                                    self.gc.get_type_id(globalobj))
         ll_assert(TL == TG, "in a root: type(LOCAL) != type(GLOBAL)")
         #
-        self.gc.trace(localobj, self._trace_drag_out_if_not_global, None)
+        self.trace_and_drag_out_of_nursery(localobj)
 
     def collect_flush_pending(self):
         # Follow the objects in the 'pending' stack and move the
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
@@ -359,6 +359,19 @@
         assert s_adr != t_adr
         self.gc.commit_transaction()
 
+    def test_commit_local_obj_with_global_references(self):
+        t, t_adr = self.malloc(S)
+        tr, tr_adr = self.malloc(SR)
+        tr.s1 = t
+        self.select_thread(1)
+        sr_adr = self.gc.stm_writebarrier(tr_adr)
+        assert sr_adr != tr_adr
+        sr = llmemory.cast_adr_to_ptr(sr_adr, lltype.Ptr(SR))
+        sr2, sr2_adr = self.malloc(SR)
+        sr.sr2 = sr2
+        sr2.s1 = t
+        self.gc.commit_transaction()
+
     def test_commit_transaction_no_references(self):
         py.test.skip("rewrite me")
         s, s_adr = self.malloc(S)


More information about the pypy-commit mailing list