[pypy-svn] r69888 - in pypy/branch/listcopyop/pypy: rlib rlib/test rpython/lltypesystem

fijal at codespeak.net fijal at codespeak.net
Fri Dec 4 12:07:31 CET 2009


Author: fijal
Date: Fri Dec  4 12:07:30 2009
New Revision: 69888

Modified:
   pypy/branch/listcopyop/pypy/rlib/rgc.py
   pypy/branch/listcopyop/pypy/rlib/test/test_rgc.py
   pypy/branch/listcopyop/pypy/rpython/lltypesystem/llmemory.py
   pypy/branch/listcopyop/pypy/rpython/lltypesystem/opimpl.py
Log:
(arigo, fijal)
* fix llmemory to handle raw_memcopy on arrays of any GC pointers.
* write tests for rgc.ll_arraycopy().


Modified: pypy/branch/listcopyop/pypy/rlib/rgc.py
==============================================================================
--- pypy/branch/listcopyop/pypy/rlib/rgc.py	(original)
+++ pypy/branch/listcopyop/pypy/rlib/rgc.py	Fri Dec  4 12:07:30 2009
@@ -333,8 +333,9 @@
     from pypy.rpython.lltypesystem.lloperation import llop
     from pypy.rpython.lltypesystem import lltype, llmemory
 
+    assert source != dest
     TP = lltype.typeOf(source).TO
-    if isinstance(TP.OF, lltype.Ptr):
+    if isinstance(TP.OF, lltype.Ptr) and TP.OF.TO._gckind == 'gc':
         if llop.gc_arraycopy(lltype.Void, source, dest, source_start, dest_start,
                             length):
             return # gc supports nicely copying lists
@@ -342,6 +343,7 @@
         while i < length:
             dest[i + dest_start] = source[i + source_start]
             i += 1
+        return
     # it's safe to do memcpy
     source_addr = llmemory.cast_ptr_to_adr(source)
     dest_addr   = llmemory.cast_ptr_to_adr(dest)

Modified: pypy/branch/listcopyop/pypy/rlib/test/test_rgc.py
==============================================================================
--- pypy/branch/listcopyop/pypy/rlib/test/test_rgc.py	(original)
+++ pypy/branch/listcopyop/pypy/rlib/test/test_rgc.py	Fri Dec  4 12:07:30 2009
@@ -68,3 +68,61 @@
         return hlstr(rgc.finish_building_buffer(ptr, 2))
 
     assert f() == 'ab'
+
+def test_ll_arraycopy_1():
+    TYPE = lltype.GcArray(lltype.Signed)
+    a1 = lltype.malloc(TYPE, 10)
+    a2 = lltype.malloc(TYPE, 6)
+    for i in range(10): a1[i] = 100 + i
+    for i in range(6):  a2[i] = 200 + i
+    rgc.ll_arraycopy(a1, a2, 4, 2, 3)
+    for i in range(10):
+        assert a1[i] == 100 + i
+    for i in range(6):
+        if 2 <= i < 5:
+	    assert a2[i] == a1[i+2]
+	else:
+	    assert a2[i] == 200 + i
+
+def test_ll_arraycopy_2():
+    TYPE = lltype.GcArray(lltype.Void)
+    a1 = lltype.malloc(TYPE, 10)
+    a2 = lltype.malloc(TYPE, 6)
+    rgc.ll_arraycopy(a1, a2, 4, 2, 3)
+    # nothing to assert here, should not crash...
+
+def test_ll_arraycopy_3():
+    S = lltype.Struct('S')    # non-gc
+    TYPE = lltype.GcArray(lltype.Ptr(S))
+    a1 = lltype.malloc(TYPE, 10)
+    a2 = lltype.malloc(TYPE, 6)
+    org1 = [None] * 10
+    org2 = [None] * 6
+    for i in range(10): a1[i] = org1[i] = lltype.malloc(S, immortal=True)
+    for i in range(6):  a2[i] = org2[i] = lltype.malloc(S, immortal=True)
+    rgc.ll_arraycopy(a1, a2, 4, 2, 3)
+    for i in range(10):
+        assert a1[i] == org1[i]
+    for i in range(6):
+        if 2 <= i < 5:
+	    assert a2[i] == a1[i+2]
+	else:
+	    assert a2[i] == org2[i]
+
+def test_ll_arraycopy_4():
+    S = lltype.GcStruct('S')
+    TYPE = lltype.GcArray(lltype.Ptr(S))
+    a1 = lltype.malloc(TYPE, 10)
+    a2 = lltype.malloc(TYPE, 6)
+    org1 = [None] * 10
+    org2 = [None] * 6
+    for i in range(10): a1[i] = org1[i] = lltype.malloc(S)
+    for i in range(6):  a2[i] = org2[i] = lltype.malloc(S)
+    rgc.ll_arraycopy(a1, a2, 4, 2, 3)
+    for i in range(10):
+        assert a1[i] == org1[i]
+    for i in range(6):
+        if 2 <= i < 5:
+	    assert a2[i] == a1[i+2]
+	else:
+	    assert a2[i] == org2[i]

Modified: pypy/branch/listcopyop/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/branch/listcopyop/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/branch/listcopyop/pypy/rpython/lltypesystem/llmemory.py	Fri Dec  4 12:07:30 2009
@@ -118,6 +118,9 @@
             return
         if isinstance(self.TYPE, lltype.ContainerType):
             PTR = lltype.Ptr(self.TYPE)
+        elif self.TYPE == GCREF:
+            self._raw_memcopy_gcrefs(srcadr, dstadr)
+            return
         else:
             PTR = lltype.Ptr(lltype.FixedSizeArray(self.TYPE, 1))
         while True:
@@ -130,6 +133,18 @@
             srcadr += ItemOffset(self.TYPE)
             dstadr += ItemOffset(self.TYPE)
 
+    def _raw_memcopy_gcrefs(self, srcadr, dstadr):
+        # special case to handle arrays of any GC pointers
+        repeat = self.repeat
+        while True:
+            data = srcadr.address[0]
+            dstadr.address[0] = data
+            repeat -= 1
+            if repeat <= 0:
+                break
+            srcadr += ItemOffset(self.TYPE)
+            dstadr += ItemOffset(self.TYPE)
+
 _end_markers = weakref.WeakKeyDictionary()  # <array of STRUCT> -> _endmarker
 class _endmarker_struct(lltype._struct):
     __slots__ = ()

Modified: pypy/branch/listcopyop/pypy/rpython/lltypesystem/opimpl.py
==============================================================================
--- pypy/branch/listcopyop/pypy/rpython/lltypesystem/opimpl.py	(original)
+++ pypy/branch/listcopyop/pypy/rpython/lltypesystem/opimpl.py	Fri Dec  4 12:07:30 2009
@@ -395,6 +395,11 @@
     return addr1 - addr2
 
 def op_gc_arraycopy(source, dest, source_start, dest_start, length):
+    A = lltype.typeOf(source)
+    assert A == lltype.typeOf(dest)
+    assert isinstance(A.TO, lltype.GcArray)
+    assert isinstance(A.TO.OF, lltype.Ptr)
+    assert A.TO.OF.TO._gckind == 'gc'
     return False # no special support
 
 def op_getfield(p, name):



More information about the Pypy-commit mailing list