Commits

Maciej Fijalkowski committed c6a93cd Merge

merge default

  • Participants
  • Parent commits 45bee24, 3705ab3
  • Branches rdict-experiments

Comments (0)

Files changed (2)

         return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype)
 
 def copy_struct_item(source, dest, si, di):
-    TP = lltype.typeOf(source)
+    TP = lltype.typeOf(source).TO.OF
     i = 0
     while i < len(TP._names):
         setattr(dest[di], TP._names[i], getattr(source[si], TP._names[i]))
+        i += 1
 
 class CopyStructEntry(ExtRegistryEntry):
     _about_ = copy_struct_item
     else:
         dest[di] = source[si]
 
+@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()
 
     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,

pypy/rlib/test/test_rgc.py

 
 
     interpret(f, [])
-    f()
+    a1 = lltype.malloc(TP, 3)
+    a2 = lltype.malloc(TP, 3)
+    a1[1].x = 3
+    a1[1].y = 15
+    rgc.copy_struct_item(a1, a2, 1, 2)
+    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)