[pypy-commit] pypy op_malloc_gc: Port the remaining rewrite tests out of test_gc, and a few fixes.
arigo
noreply at buildbot.pypy.org
Sun Dec 18 15:51:49 CET 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: op_malloc_gc
Changeset: r50655:cc7e577077b7
Date: 2011-12-18 15:51 +0100
http://bitbucket.org/pypy/pypy/changeset/cc7e577077b7/
Log: Port the remaining rewrite tests out of test_gc, and a few fixes.
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -602,6 +602,9 @@
funcaddr = llmemory.cast_ptr_to_adr(funcptr)
return cpu.cast_adr_to_int(funcaddr) # this may return 0
+ def has_write_barrier_from_array(self, cpu):
+ return self.get_write_barrier_from_array_fn(cpu) != 0
+
class GcLLDescr_framework(GcLLDescription):
DEBUG = False # forced to True by x86/test/test_zrpy_gc.py
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -46,8 +46,11 @@
if op.is_malloc():
self.handle_malloc_operation(op)
continue
- elif op.can_malloc() or op.getopnum() == rop.LABEL:
+ elif op.can_malloc():
self.emitting_an_operation_that_can_collect()
+ elif op.getopnum() == rop.LABEL:
+ self.emitting_an_operation_that_can_collect()
+ self.known_lengths.clear()
# ---------- write barriers ----------
if self.gc_ll_descr.write_barrier_descr is not None:
if op.getopnum() == rop.SETFIELD_GC:
@@ -98,15 +101,16 @@
def handle_new_array(self, arraydescr, op):
v_length = op.getarg(0)
total_size = -1
- if arraydescr.itemsize == 0:
- total_size = arraydescr.basesize
- elif isinstance(v_length, ConstInt):
+ if isinstance(v_length, ConstInt):
num_elem = v_length.getint()
+ self.known_lengths[op.result] = num_elem
try:
var_size = ovfcheck(arraydescr.itemsize * num_elem)
total_size = ovfcheck(arraydescr.basesize + var_size)
except OverflowError:
pass # total_size is still -1
+ elif arraydescr.itemsize == 0:
+ total_size = arraydescr.basesize
if total_size >= 0:
self.gen_malloc_nursery(total_size, op.result)
self.gen_initialize_tid(op.result, arraydescr.tid)
@@ -282,7 +286,7 @@
def gen_write_barrier_array(self, v_base, v_index, v_value):
write_barrier_descr = self.gc_ll_descr.write_barrier_descr
- if write_barrier_descr.get_write_barrier_from_array_fn(self.cpu) != 0:
+ if write_barrier_descr.has_write_barrier_from_array(self.cpu):
# If we know statically the length of 'v', and it is not too
# big, then produce a regular write_barrier. If it's unknown or
# too big, produce instead a write_barrier_from_array.
diff --git a/pypy/jit/backend/llsupport/test/test_gc.py b/pypy/jit/backend/llsupport/test/test_gc.py
--- a/pypy/jit/backend/llsupport/test/test_gc.py
+++ b/pypy/jit/backend/llsupport/test/test_gc.py
@@ -456,186 +456,6 @@
assert operations2 == operations
assert gcrefs == [s_gcref]
- def test_rewrite_assembler_2(self):
- # check write barriers before SETFIELD_GC
- v_base = BoxPtr()
- v_value = BoxPtr()
- field_descr = AbstractDescr()
- operations = [
- ResOperation(rop.SETFIELD_GC, [v_base, v_value], None,
- descr=field_descr),
- ]
- gc_ll_descr = self.gc_ll_descr
- operations = get_deep_immutable_oplist(operations)
- operations = gc_ll_descr.rewrite_assembler(self.fake_cpu, operations,
- [])
- assert len(operations) == 2
- #
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_value
- assert operations[0].result is None
- #
- assert operations[1].getopnum() == rop.SETFIELD_RAW
- assert operations[1].getarg(0) == v_base
- assert operations[1].getarg(1) == v_value
- assert operations[1].getdescr() == field_descr
-
- def test_rewrite_assembler_3(self):
- # check write barriers before SETARRAYITEM_GC
- for new_length in (-1, 5, 5000):
- v_base = BoxPtr()
- v_index = BoxInt()
- v_value = BoxPtr()
- array_descr = AbstractDescr()
- operations = [
- ResOperation(rop.SETARRAYITEM_GC, [v_base, v_index, v_value],
- None, descr=array_descr),
- ]
- rewriter = GcRewriterAssembler(self.gc_ll_descr, self.fake_cpu)
- if new_length >= 0:
- rewriter.known_lengths[v_base] = new_length
- operations = get_deep_immutable_oplist(operations)
- operations = rewriter.rewrite(operations)
- assert len(operations) == 2
- #
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_value
- assert operations[0].result is None
- #
- assert operations[1].getopnum() == rop.SETARRAYITEM_RAW
- assert operations[1].getarg(0) == v_base
- assert operations[1].getarg(1) == v_index
- assert operations[1].getarg(2) == v_value
- assert operations[1].getdescr() == array_descr
-
- def test_rewrite_assembler_4(self):
- # check write barriers before SETARRAYITEM_GC,
- # if we have actually a write_barrier_from_array.
- self.llop1._have_wb_from_array = True
- for new_length in (-1, 5, 5000):
- v_base = BoxPtr()
- v_index = BoxInt()
- v_value = BoxPtr()
- array_descr = AbstractDescr()
- operations = [
- ResOperation(rop.SETARRAYITEM_GC, [v_base, v_index, v_value],
- None, descr=array_descr),
- ]
- rewriter = GcRewriterAssembler(self.gc_ll_descr, self.fake_cpu)
- if new_length >= 0:
- rewriter.known_lengths[v_base] = new_length
- operations = get_deep_immutable_oplist(operations)
- operations = rewriter.rewrite(operations)
- assert len(operations) == 2
- #
- if 0 <= new_length < 130:
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_value
- else:
- assert operations[0].getopnum() == rop.COND_CALL_GC_WB_ARRAY
- assert operations[0].getarg(0) == v_base
- assert operations[0].getarg(1) == v_index
- assert operations[0].getarg(2) == v_value
- assert operations[0].result is None
- #
- assert operations[1].getopnum() == rop.SETARRAYITEM_RAW
- assert operations[1].getarg(0) == v_base
- assert operations[1].getarg(1) == v_index
- assert operations[1].getarg(2) == v_value
- assert operations[1].getdescr() == array_descr
-
- def test_rewrite_assembler_5(self):
- S = lltype.GcStruct('S')
- A = lltype.GcArray(lltype.Struct('A', ('x', lltype.Ptr(S))))
- interiordescr = get_interiorfield_descr(self.gc_ll_descr, A, 'x')
- wbdescr = self.gc_ll_descr.write_barrier_descr
- ops = parse("""
- [p1, p2]
- setinteriorfield_gc(p1, 0, p2, descr=interiordescr)
- jump(p1, p2)
- """, namespace=locals())
- expected = parse("""
- [p1, p2]
- cond_call_gc_wb(p1, p2, descr=wbdescr)
- setinteriorfield_raw(p1, 0, p2, descr=interiordescr)
- jump(p1, p2)
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
- def test_rewrite_assembler_initialization_store(self):
- S = lltype.GcStruct('S', ('x', lltype.Signed))
- sdescr = get_size_descr(self.gc_ll_descr, S)
- xdescr = get_field_descr(self.gc_ll_descr, S, 'x')
- ops = parse("""
- [p1]
- p0 = new(descr=sdescr)
- setfield_gc(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- expected = parse("""
- [p1]
- p0 = new(descr=sdescr)
- # no write barrier
- setfield_gc(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
- def test_rewrite_assembler_initialization_store_2(self):
- S = lltype.GcStruct('S', ('parent', OBJECT),
- ('x', lltype.Signed))
- s_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
- wbdescr = self.gc_ll_descr.write_barrier_descr
- xdescr = get_field_descr(self.gc_ll_descr, S, 'x')
- ops = parse("""
- [p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
- p3 = new_with_vtable(ConstClass(s_vtable))
- setfield_gc(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- expected = parse("""
- [p1]
- p0 = new_with_vtable(ConstClass(s_vtable))
- p3 = new_with_vtable(ConstClass(s_vtable))
- cond_call_gc_wb(p0, p1, descr=wbdescr)
- setfield_raw(p0, p1, descr=xdescr)
- jump()
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
- def test_rewrite_assembler_initialization_store_3(self):
- A = lltype.GcArray(lltype.Ptr(lltype.GcStruct('S')))
- arraydescr = get_array_descr(self.gc_ll_descr, A)
- ops = parse("""
- [p1]
- p0 = new_array(3, descr=arraydescr)
- setarrayitem_gc(p0, 0, p1, descr=arraydescr)
- jump()
- """, namespace=locals())
- expected = parse("""
- [p1]
- p0 = new_array(3, descr=arraydescr)
- setarrayitem_gc(p0, 0, p1, descr=arraydescr)
- jump()
- """, namespace=locals())
- operations = get_deep_immutable_oplist(ops.operations)
- operations = self.gc_ll_descr.rewrite_assembler(self.fake_cpu,
- operations, [])
- equaloplists(operations, expected.operations)
-
class TestFrameworkMiniMark(TestFramework):
gc = 'minimark'
diff --git a/pypy/jit/backend/llsupport/test/test_rewrite.py b/pypy/jit/backend/llsupport/test/test_rewrite.py
--- a/pypy/jit/backend/llsupport/test/test_rewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_rewrite.py
@@ -30,12 +30,24 @@
A = lltype.GcArray(lltype.Signed)
adescr = get_array_descr(self.gc_ll_descr, A)
adescr.tid = 4321
- alendescr = get_field_arraylen_descr(self.gc_ll_descr, A)
+ alendescr = adescr.lendescr
#
B = lltype.GcArray(lltype.Char)
bdescr = get_array_descr(self.gc_ll_descr, B)
bdescr.tid = 8765
- blendescr = get_field_arraylen_descr(self.gc_ll_descr, B)
+ blendescr = bdescr.lendescr
+ #
+ C = lltype.GcArray(lltype.Ptr(S))
+ cdescr = get_array_descr(self.gc_ll_descr, C)
+ cdescr.tid = 8111
+ clendescr = cdescr.lendescr
+ #
+ INTERIOR = lltype.GcArray(('z', lltype.Ptr(S)))
+ interiordescr = get_array_descr(self.gc_ll_descr, INTERIOR)
+ interiordescr.tid = 1291
+ interiorlendescr = interiordescr.lendescr
+ interiorzdescr = get_interiorfield_descr(self.gc_ll_descr,
+ INTERIOR, 'z')
#
E = lltype.GcStruct('Empty')
edescr = get_size_descr(self.gc_ll_descr, E)
@@ -183,6 +195,8 @@
gcdescr = get_description(config_)
self.gc_ll_descr = GcLLDescr_framework(gcdescr, None, None, None,
really_not_translated=True)
+ self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
+ lambda cpu: True)
#
class FakeCPU(object):
def sizeof(self, STRUCT):
@@ -423,3 +437,185 @@
setfield_raw(p1, p2, descr=tzdescr)
jump()
""")
+
+ def test_write_barrier_before_array_without_from_array(self):
+ self.gc_ll_descr.write_barrier_descr.has_write_barrier_from_array = (
+ lambda cpu: False)
+ self.check_rewrite("""
+ [p1, i2, p3]
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [p1, i2, p3]
+ cond_call_gc_wb(p1, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_short_array(self):
+ self.check_rewrite("""
+ [i2, p3]
+ p1 = new_array(129, descr=cdescr)
+ call(123456)
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [i2, p3]
+ p1 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(cdescr.basesize + 129 * cdescr.itemsize)d)
+ setfield_gc(p1, 8111, descr=tiddescr)
+ setfield_gc(p1, 129, descr=clendescr)
+ call(123456)
+ cond_call_gc_wb(p1, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_long_array(self):
+ # the limit of "being too long" is fixed, arbitrarily, at 130
+ self.check_rewrite("""
+ [i2, p3]
+ p1 = new_array(130, descr=cdescr)
+ call(123456)
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [i2, p3]
+ p1 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(cdescr.basesize + 130 * cdescr.itemsize)d)
+ setfield_gc(p1, 8111, descr=tiddescr)
+ setfield_gc(p1, 130, descr=clendescr)
+ call(123456)
+ cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_unknown_array(self):
+ self.check_rewrite("""
+ [p1, i2, p3]
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [p1, i2, p3]
+ cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_label_makes_size_unknown(self):
+ self.check_rewrite("""
+ [i2, p3]
+ p1 = new_array(5, descr=cdescr)
+ label(p1, i2, p3)
+ setarrayitem_gc(p1, i2, p3, descr=cdescr)
+ jump()
+ """, """
+ [i2, p3]
+ p1 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(cdescr.basesize + 5 * cdescr.itemsize)d)
+ setfield_gc(p1, 8111, descr=tiddescr)
+ setfield_gc(p1, 5, descr=clendescr)
+ label(p1, i2, p3)
+ cond_call_gc_wb_array(p1, i2, p3, descr=wbdescr)
+ setarrayitem_raw(p1, i2, p3, descr=cdescr)
+ jump()
+ """)
+
+ def test_write_barrier_before_setinteriorfield_gc(self):
+ self.check_rewrite("""
+ [p1, p2]
+ setinteriorfield_gc(p1, 0, p2, descr=interiorzdescr)
+ jump(p1, p2)
+ """, """
+ [p1, p2]
+ cond_call_gc_wb(p1, p2, descr=wbdescr)
+ setinteriorfield_raw(p1, 0, p2, descr=interiorzdescr)
+ jump(p1, p2)
+ """)
+
+ def test_initialization_store(self):
+ self.check_rewrite("""
+ [p1]
+ p0 = new(descr=tdescr)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(tdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """)
+
+ def test_initialization_store_2(self):
+ self.check_rewrite("""
+ []
+ p0 = new(descr=tdescr)
+ p1 = new(descr=sdescr)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ []
+ p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(tdescr.size + sdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ p1 = int_add(p0, %(tdescr.size)d)
+ setfield_gc(p1, 1234, descr=tiddescr)
+ # <<<no cond_call_gc_wb here>>>
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """)
+
+ def test_initialization_store_array(self):
+ self.check_rewrite("""
+ [p1, i2]
+ p0 = new_array(5, descr=cdescr)
+ setarrayitem_gc(p0, i2, p1, descr=cdescr)
+ jump()
+ """, """
+ [p1, i2]
+ p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(cdescr.basesize + 5 * cdescr.itemsize)d)
+ setfield_gc(p0, 8111, descr=tiddescr)
+ setfield_gc(p0, 5, descr=clendescr)
+ setarrayitem_gc(p0, i2, p1, descr=cdescr)
+ jump()
+ """)
+
+ def test_non_initialization_store(self):
+ self.check_rewrite("""
+ [i0]
+ p0 = new(descr=tdescr)
+ p1 = newstr(i0)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ [i0]
+ p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(tdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ p1 = call_malloc_gc(ConstClass(malloc_str), i0)
+ cond_call_gc_wb(p0, p1, descr=wbdescr)
+ setfield_raw(p0, p1, descr=tzdescr)
+ jump()
+ """)
+
+ def test_non_initialization_store_label(self):
+ self.check_rewrite("""
+ [p1]
+ p0 = new(descr=tdescr)
+ label(p0, p1)
+ setfield_gc(p0, p1, descr=tzdescr)
+ jump()
+ """, """
+ [p1]
+ p0 = call_malloc_nursery(ConstClass(malloc_nursery), \
+ %(tdescr.size)d)
+ setfield_gc(p0, 5678, descr=tiddescr)
+ label(p0, p1)
+ cond_call_gc_wb(p0, p1, descr=wbdescr)
+ setfield_raw(p0, p1, descr=tzdescr)
+ jump()
+ """)
More information about the pypy-commit
mailing list