Author: Maciej Fijalkowski <[email protected]>
Branch: rdict-experiments-3
Changeset: r67597:7048d98f967f
Date: 2013-10-25 13:22 +0200
http://bitbucket.org/pypy/pypy/changeset/7048d98f967f/

Log:    support something more advanced in writebarrier before copy (only
        llimpl actually, since the actual one seems to work), use
        ll_arraycopy in rdict

diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -7,6 +7,7 @@
 from rpython.rlib.objectmodel import we_are_translated, enforceargs, specialize
 from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.rtyper.lltypesystem import lltype, llmemory
+from rpython.rlib.objectmodel import keepalive_until_here
 
 # ____________________________________________________________
 # General GC features
@@ -137,15 +138,38 @@
         hop.exception_cannot_occur()
         return hop.genop(opname, vlist, resulttype = hop.r_result.lowleveltype)
 
-def copy_struct_item(source, dest, si, di):
[email protected]()
+def copy_struct_item(source, dest, si, di, emit_write_barrier=True):
+    """ Copy struct items. There are two versions - one that emits
+    write barrier and one that does not. The one that does not *must*
+    have write barrier called before the copy
+    """
+    TP = lltype.typeOf(source).TO
+    if emit_write_barrier:
+        _copy_struct_item(source, dest, si, di)
+    else:
+        source_addr = llmemory.cast_ptr_to_adr(source)
+        dest_addr   = llmemory.cast_ptr_to_adr(dest)
+        cp_source_addr = (source_addr + llmemory.itemoffsetof(TP, 0) +
+                          llmemory.sizeof(TP.OF) * si)
+        cp_dest_addr = (dest_addr + llmemory.itemoffsetof(TP, 0) +
+                        llmemory.sizeof(TP.OF) * di)
+        llmemory.raw_memcopy(cp_source_addr, cp_dest_addr,
+                             llmemory.sizeof(TP.OF))
+        keepalive_until_here(source)
+        keepalive_until_here(dest)
+copy_struct_item._always_inline_ = True
+
+def _copy_struct_item(source, dest, si, di):
     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]))
+        setattr(dest[di], TP._names[i],
+                getattr(source[si], TP._names[i]))
         i += 1
 
 class CopyStructEntry(ExtRegistryEntry):
-    _about_ = copy_struct_item
+    _about_ = _copy_struct_item
 
     def compute_result_annotation(self, s_source, s_dest, si, di):
         pass
@@ -189,7 +213,6 @@
 @specialize.ll()
 def ll_arraycopy(source, dest, source_start, dest_start, length):
     from rpython.rtyper.lltypesystem.lloperation import llop
-    from rpython.rlib.objectmodel import keepalive_until_here
 
     # XXX: Hack to ensure that we get a proper effectinfo.write_descrs_arrays
     # and also, maybe, speed up very small cases
@@ -266,7 +289,7 @@
     func._dont_inline_ = True
     func._no_release_gil_ = True
     return func
-    
+
 def no_collect(func):
     func._dont_inline_ = True
     func._gc_no_collect_ = True
diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py
--- a/rpython/rlib/test/test_rgc.py
+++ b/rpython/rlib/test/test_rgc.py
@@ -228,3 +228,18 @@
     x1 = X()
     n = rgc.get_rpy_memory_usage(rgc.cast_instance_to_gcref(x1))
     assert n >= 8 and n <= 64
+
+def test_copy_struct_items_no_wb():
+    S = lltype.GcArray(lltype.Struct('x', ('a', lltype.Signed), ('b', 
lltype.Signed)))
+
+    def f():
+        a = lltype.malloc(S, 1)
+        a[0].a = 3
+        a[0].b = 13
+        b = lltype.malloc(S, 1)
+        rgc.copy_struct_item(a, b, 0, 0, False)
+        assert b[0].a == 3
+        assert b[0].b == 13
+
+    f()
+    interpret(f, [])
diff --git a/rpython/rtyper/lltypesystem/opimpl.py 
b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -522,8 +522,10 @@
     A = lltype.typeOf(source)
     assert A == lltype.typeOf(dest)
     if isinstance(A.TO, lltype.GcArray):
-        assert isinstance(A.TO.OF, lltype.Ptr)
-        assert A.TO.OF.TO._gckind == 'gc'
+        if isinstance(A.TO.OF, lltype.Ptr):
+            assert A.TO.OF.TO._gckind == 'gc'
+        else:
+            assert isinstance(A.TO.OF, lltype.Struct)
     else:
         assert isinstance(A.TO, lltype.GcStruct)
         assert A.TO._arrayfld is not None
diff --git a/rpython/rtyper/lltypesystem/rdict.py 
b/rpython/rtyper/lltypesystem/rdict.py
--- a/rpython/rtyper/lltypesystem/rdict.py
+++ b/rpython/rtyper/lltypesystem/rdict.py
@@ -624,20 +624,7 @@
         return True
 
     newitems = lltype.malloc(lltype.typeOf(d).TO.entries.TO, new_allocated)
-    #
-    # XXX we should do this with rgc.ll_arraycopy()!!
-    ENTRY = lltype.typeOf(d).TO.entries.TO.OF
-    i = 0
-    while i < len(d.entries):
-        src = d.entries[i]
-        dst = newitems[i]
-        dst.key = src.key
-        dst.value = src.value
-        if hasattr(ENTRY, 'f_hash'):
-            dst.f_hash = src.f_hash
-        if hasattr(ENTRY, 'f_valid'):
-            dst.f_valid = src.f_valid
-        i += 1
+    rgc.ll_arraycopy(d.entries, newitems, 0, 0, len(d.entries))
     d.entries = newitems
     return False
 
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to