[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