Author: Maciej Fijalkowski <fij...@gmail.com> Branch: Changeset: r59779:99da6b4f5a3f Date: 2013-01-05 22:25 +0200 http://bitbucket.org/pypy/pypy/changeset/99da6b4f5a3f/
Log: merge diff --git a/pypy/rlib/rgc.py b/pypy/rlib/rgc.py --- a/pypy/rlib/rgc.py +++ b/pypy/rlib/rgc.py @@ -139,6 +139,40 @@ hop.exception_cannot_occur() return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype) +def copy_struct_item(source, dest, si, di): + TP = lltype.typeOf(source) + i = 0 + while i < len(TP._names): + setattr(dest[di], TP._names[i], getattr(source[si], TP._names[i])) + +class CopyStructEntry(ExtRegistryEntry): + _about_ = copy_struct_item + + def compute_result_annotation(self, s_source, s_dest, si, di): + pass + + def specialize_call(self, hop): + v_source, v_dest, v_si, v_di = hop.inputargs(hop.args_r[0], + hop.args_r[1], + lltype.Signed, + lltype.Signed) + hop.exception_cannot_occur() + TP = v_source.concretetype.TO.OF + for name, TP in TP._flds.iteritems(): + c_name = hop.inputconst(lltype.Void, name) + v_fld = hop.genop('getinteriorfield', [v_source, v_si, c_name], + resulttype=TP) + hop.genop('setinteriorfield', [v_dest, v_di, c_name, v_fld]) + + +@specialize.ll() +def copy_item(source, dest, si, di): + TP = lltype.typeOf(source) + if isinstance(TP.TO.OF, lltype.Struct): + copy_struct_item(source, dest, si, di) + else: + dest[di] = source[si] + @jit.oopspec('list.ll_arraycopy(source, dest, source_start, dest_start, length)') @enforceargs(None, None, int, int, int) @specialize.ll() @@ -150,7 +184,7 @@ # and also, maybe, speed up very small cases if length <= 1: if length == 1: - dest[dest_start] = source[source_start] + copy_item(source, dest, source_start, dest_start) return # supports non-overlapping copies only @@ -170,7 +204,7 @@ # if the write barrier is not supported, copy by hand i = 0 while i < length: - dest[i + dest_start] = source[i + source_start] + copy_item(source, dest, i + source_start, i + dest_start) i += 1 return source_addr = llmemory.cast_ptr_to_adr(source) 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 @@ -134,6 +134,24 @@ assert check.called +def test_ll_arraycopy_array_of_structs(): + TP = lltype.GcArray(lltype.Struct('x', ('x', lltype.Signed), + ('y', lltype.Signed))) + def f(): + a1 = lltype.malloc(TP, 3) + a2 = lltype.malloc(TP, 3) + for i in range(3): + a1[i].x = 2 * i + a1[i].y = 2 * i + 1 + rgc.ll_arraycopy(a1, a2, 0, 0, 3) + for i in range(3): + assert a2[i].x == 2 * i + assert a2[i].y == 2 * i + 1 + + + interpret(f, []) + f() + def test_ll_arraycopy_small(): TYPE = lltype.GcArray(lltype.Signed) for length in range(5): diff --git a/pypy/rpython/lltypesystem/test/test_lltype.py b/pypy/rpython/lltypesystem/test/test_lltype.py --- a/pypy/rpython/lltypesystem/test/test_lltype.py +++ b/pypy/rpython/lltypesystem/test/test_lltype.py @@ -808,7 +808,6 @@ assert F.RESULT == Signed assert F.ARGS == (Signed,) - class TestTrackAllocation: def test_automatic_tracking(self): # calls to start_tracking_allocations/stop_tracking_allocations _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit