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