Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r54799:605a0a476290
Date: 2012-04-29 10:04 +0200
http://bitbucket.org/pypy/pypy/changeset/605a0a476290/

Log:    Fix the first half of the test.

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
@@ -238,6 +238,9 @@
         # they are simply added to 'pending'.
         self.collect_roots_from_stack()
         #
+        # Find the roots that are living in raw structures.
+        self.collect_from_raw_structures()
+        #
         # Also find the roots that are the local copy of GCFLAG_WAS_COPIED
         # objects.
         if not self.in_main_thread:
@@ -382,6 +385,10 @@
         self.gc.root_walker.walk_current_stack_roots(
             StmGCTLS._trace_drag_out1, self)
 
+    def collect_from_raw_structures(self):
+        self.gc.root_walker.walk_current_nongc_roots(
+            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
         # they are global.  If necessary, the referenced objects are copied
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
@@ -133,6 +133,8 @@
 class FakeRootWalker:
     def walk_current_stack_roots(self, *args):
         pass     # no stack roots in this test file
+    def walk_current_nongc_roots(self, *args):
+        pass     # no nongc roots in this test file
 
 
 class StmGCTests:
@@ -848,3 +850,17 @@
         assert a == sr1_adr
         a = self.gc.stm_normalize_global(tr1_adr)
         assert a == sr1_adr
+
+    def test_prebuilt_nongc(self):
+        from pypy.rpython.memory.gc.test import test_stmtls
+        self.gc.root_walker = test_stmtls.FakeRootWalker()
+        NONGC = lltype.Struct('NONGC', ('s', lltype.Ptr(S)))
+        nongc = lltype.malloc(NONGC, immortal=True, flavor='raw')
+        self.gc.root_walker.prebuilt_nongc = [(nongc, 's')]
+        #
+        s, _ = self.malloc(S, globl=False)      # a local object
+        nongc.s = s
+        self.gc.collect(0)                      # keeps LOCAL
+        s = nongc.s                             # reload, it moved
+        s_adr = llmemory.cast_ptr_to_adr(s)
+        self.checkflags(s_adr, False, False)    # check it survived
diff --git a/pypy/rpython/memory/gc/test/test_stmtls.py 
b/pypy/rpython/memory/gc/test/test_stmtls.py
--- a/pypy/rpython/memory/gc/test/test_stmtls.py
+++ b/pypy/rpython/memory/gc/test/test_stmtls.py
@@ -25,19 +25,36 @@
     pass
 
 class FakeRootWalker:
-    def walk_current_stack_roots(self, callback, arg):
+    current_stack = ()
+    prebuilt_nongc = ()
+
+    def collect_list(self, lst):
         A = lltype.Array(llmemory.Address)
-        roots = lltype.malloc(A, len(self.current_stack), flavor='raw')
-        for i in range(len(self.current_stack)):
-            roots[i] = llmemory.cast_ptr_to_adr(self.current_stack[i])
-        for i in range(len(self.current_stack)):
+        roots = lltype.malloc(A, len(lst), flavor='raw')
+        for i in range(len(lst)):
+            roots[i] = llmemory.cast_ptr_to_adr(lst[i])
+        for i in range(len(lst)):
             root = lltype.direct_ptradd(lltype.direct_arrayitems(roots), i)
             root = llmemory.cast_ptr_to_adr(root)
+            yield root
+        for i in range(len(lst)):
+            P = lltype.typeOf(lst[i])
+            lst[i] = llmemory.cast_adr_to_ptr(roots[i], P)
+        lltype.free(roots, flavor='raw')
+
+    def walk_current_stack_roots(self, callback, arg):
+        for root in self.collect_list(self.current_stack):
             callback(arg, root)
-        for i in range(len(self.current_stack)):
-            P = lltype.typeOf(self.current_stack[i])
-            self.current_stack[i] = llmemory.cast_adr_to_ptr(roots[i], P)
-        lltype.free(roots, flavor='raw')
+
+    def collect_field_list(self, lst):
+        for structptr, field in lst:
+            root = lltype.direct_fieldptr(structptr, field)
+            root = llmemory.cast_ptr_to_adr(root)
+            yield root
+
+    def walk_current_nongc_roots(self, callback, arg):
+        for root in self.collect_field_list(self.prebuilt_nongc):
+            callback(arg, root)
 
 class FakeGC:
     from pypy.rpython.memory.support import AddressDict, null_address_dict
diff --git a/pypy/rpython/memory/gctransform/stmframework.py 
b/pypy/rpython/memory/gctransform/stmframework.py
--- a/pypy/rpython/memory/gctransform/stmframework.py
+++ b/pypy/rpython/memory/gctransform/stmframework.py
@@ -198,3 +198,15 @@
         self.rootstackhook(collect_stack_root, arg,
                            stackgcdata.root_stack_base,
                            stackgcdata.root_stack_top)
+
+    @specialize.argtype(2)
+    def walk_current_nongc_roots(self, collect_nongc_root, arg):
+        gcdata = self.gcdata
+        gc = self.gc
+        addr = gcdata.static_root_start
+        end = gcdata.static_root_nongcend
+        while addr != end:
+            result = addr.address[0]
+            if gc.points_to_valid_gc_object(result):
+                collect_nongc_root(arg, result)
+            addr += sizeofaddr
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to