[pypy-svn] r79077 - in pypy/trunk/pypy/jit/backend/llsupport: . test

fijal at codespeak.net fijal at codespeak.net
Sun Nov 14 12:12:56 CET 2010


Author: fijal
Date: Sun Nov 14 12:12:55 2010
New Revision: 79077

Modified:
   pypy/trunk/pypy/jit/backend/llsupport/gc.py
   pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
Log:
Implement an optimization - when we initialize the store don't call write
barrier (this is for examples where new is followed immediately by
setfield/arrayitem set)


Modified: pypy/trunk/pypy/jit/backend/llsupport/gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/gc.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/gc.py	Sun Nov 14 12:12:55 2010
@@ -573,6 +573,9 @@
         #   GETFIELD_RAW from the array 'gcrefs.list'.
         #
         newops = []
+        # we can only remember one malloc since the next malloc can possibly
+        # collect
+        last_malloc = None
         for op in operations:
             if op.getopnum() == rop.DEBUG_MERGE_POINT:
                 continue
@@ -590,22 +593,32 @@
                                                    [ConstInt(addr)], box,
                                                    self.single_gcref_descr))
                         op.setarg(i, box)
+            if op.is_malloc():
+                last_malloc = op.result
+            elif op.can_malloc():
+                last_malloc = None
             # ---------- write barrier for SETFIELD_GC ----------
             if op.getopnum() == rop.SETFIELD_GC:
-                v = op.getarg(1)
-                if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
-                                             bool(v.value)): # store a non-NULL
-                    self._gen_write_barrier(newops, op.getarg(0), v)
-                    op = op.copy_and_change(rop.SETFIELD_RAW)
+                val = op.getarg(0)
+                # no need for a write barrier in the case of previous malloc
+                if val is not last_malloc:
+                    v = op.getarg(1)
+                    if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+                                            bool(v.value)): # store a non-NULL
+                        self._gen_write_barrier(newops, op.getarg(0), v)
+                        op = op.copy_and_change(rop.SETFIELD_RAW)
             # ---------- write barrier for SETARRAYITEM_GC ----------
             if op.getopnum() == rop.SETARRAYITEM_GC:
-                v = op.getarg(2)
-                if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
-                                             bool(v.value)): # store a non-NULL
-                    # XXX detect when we should produce a
-                    # write_barrier_from_array
-                    self._gen_write_barrier(newops, op.getarg(0), v)
-                    op = op.copy_and_change(rop.SETARRAYITEM_RAW)
+                val = op.getarg(0)
+                # no need for a write barrier in the case of previous malloc
+                if val is not last_malloc:
+                    v = op.getarg(2)
+                    if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
+                                            bool(v.value)): # store a non-NULL
+                        # XXX detect when we should produce a
+                        # write_barrier_from_array
+                        self._gen_write_barrier(newops, op.getarg(0), v)
+                        op = op.copy_and_change(rop.SETARRAYITEM_RAW)
             # ----------
             newops.append(op)
         del operations[:]

Modified: pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py
==============================================================================
--- pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py	(original)
+++ pypy/trunk/pypy/jit/backend/llsupport/test/test_gc.py	Sun Nov 14 12:12:55 2010
@@ -6,7 +6,9 @@
 from pypy.jit.backend.llsupport.gc import *
 from pypy.jit.backend.llsupport import symbolic
 from pypy.jit.metainterp.gc import get_description
-
+from pypy.jit.tool.oparser import parse
+from pypy.rpython.lltypesystem.rclass import OBJECT, OBJECT_VTABLE
+from pypy.jit.metainterp.test.test_optimizeopt import equaloplists
 
 def test_boehm():
     gc_ll_descr = GcLLDescr_boehm(None, None, None)
@@ -394,6 +396,68 @@
         assert operations[1].getarg(2) == v_value
         assert operations[1].getdescr() == array_descr
 
+    def test_rewrite_assembler_initialization_store(self):
+        S = lltype.GcStruct('S', ('parent', OBJECT),
+                            ('x', lltype.Signed))
+        s_vtable = lltype.malloc(OBJECT_VTABLE, immortal=True)
+        xdescr = get_field_descr(self.gc_ll_descr, S, 'x')
+        ops = parse("""
+        [p1]
+        p0 = 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))
+        # no write barrier
+        setfield_gc(p0, p1, descr=xdescr)
+        jump()
+        """, namespace=locals())
+        self.gc_ll_descr.rewrite_assembler(self.fake_cpu, ops.operations)
+        equaloplists(ops.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())
+        self.gc_ll_descr.rewrite_assembler(self.fake_cpu, ops.operations)
+        equaloplists(ops.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())
+        self.gc_ll_descr.rewrite_assembler(self.fake_cpu, ops.operations)
+        equaloplists(ops.operations, expected.operations)
 
 class TestFrameworkMiniMark(TestFramework):
     gc = 'minimark'



More information about the Pypy-commit mailing list