[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