[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