[pypy-commit] pypy default: a fix for writebarrier (a bit hard to test otherwise) and a direct test

fijal noreply at buildbot.pypy.org
Sat Jan 5 21:36:51 CET 2013


Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: 
Changeset: r59782:3705ab3e421a
Date: 2013-01-05 22:36 +0200
http://bitbucket.org/pypy/pypy/changeset/3705ab3e421a/

Log:	a fix for writebarrier (a bit hard to test otherwise) and a direct
	test

diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py
--- a/pypy/rlib/rgc.py
+++ b/pypy/rlib/rgc.py
@@ -174,6 +174,15 @@
     else:
         dest[di] = source[si]
 
+ at specialize.memo()
+def _contains_gcptr(TP):
+    if not isinstance(TP, lltype.Struct):
+        return False
+    for TP in TP._flds.itervalues():
+        if isinstance(TP, lltype.Ptr) and TP.TO._gckind == 'gc':
+            return True
+    return False
+
 @jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start, length)')
 @enforceargs(None, None, int, int, int)
 @specialize.ll()
@@ -196,7 +205,8 @@
 
     TP = lltype.typeOf(source).TO
     assert TP == lltype.typeOf(dest).TO
-    if isinstance(TP.OF, lltype.Ptr) and TP.OF.TO._gckind == 'gc':
+    if isinstance(TP.OF, lltype.Ptr) and (TP.OF.TO._gckind == 'gc'
+                                          or _contains_gcptr(TP.OF.TO)):
         # perform a write barrier that copies necessary flags from
         # source to dest
         if not llop.gc_writebarrier_before_copy(lltype.Bool, source, dest,
diff --git a/pypy/rlib/test/test_rgc.py b/pypy/rlib/test/test_rgc.py
--- a/pypy/rlib/test/test_rgc.py
+++ b/pypy/rlib/test/test_rgc.py
@@ -158,6 +158,14 @@
     assert a2[2].x == 3
     assert a2[2].y == 15
 
+def test__contains_gcptr():
+    assert not rgc._contains_gcptr(lltype.Signed)
+    assert not rgc._contains_gcptr(lltype.Struct('x', ('x', lltype.Signed)))
+    assert rgc._contains_gcptr(lltype.Struct('x', ('x', lltype.Signed),
+                           ('y', lltype.Ptr(lltype.GcArray(lltype.Signed)))))
+    assert rgc._contains_gcptr(lltype.Struct('x', ('x', lltype.Signed),
+                           ('y', llmemory.GCREF)))
+
 def test_ll_arraycopy_small():
     TYPE = lltype.GcArray(lltype.Signed)
     for length in range(5):


More information about the pypy-commit mailing list